Version: 6000.3
语言: 中文
为复杂数据类型定义自定义控件属性
将自定义控件绑定到数据

自定义 UXML 属性

你可以自定义UXL属性名称、属性的行为,并添加装饰器和自定义属性抽屉一种 Unity 功能,允许你使用脚本上的属性或通过控制特定 Serializable 类的外观
来自定义检查器窗口中某些控件的外观更多信息 请参阅术语表
在 UI Builder 中。

重命名 UXML 属性

可以通过name参数的UxmlAttribute属性。

下面显示了具有重命名属性的自定义控件的示例:

using UnityEngine.UIElements;

[UxmlElement]
public partial class CustomAttributeNameExample : VisualElement
{
    [UxmlAttribute("character-name")]
    public string myStringValue { get; set; }

    [UxmlAttribute("credits")]
    public float myFloatValue { get; set; }

    [UxmlAttribute("level")]
    public int myIntValue { get; set; }

    [UxmlAttribute("usage")]
    public UsageHints myEnumValue { get; set; }
}

下面显示了一个具有重命名属性的UXML文档示例:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <CustomAttributeNameExample character-name="Karl" credits="1.23" level="1" usage="DynamicColor" />
</ui:UXML>

如果重命名属性并希望具有旧名称的 UXML 文件保持兼容,请将obsoleteNames参数设置为UxmlAttribute属性。

以下示例演示如何使用obsoleteNames论点:

using UnityEngine.UIElements;

[UxmlElement]
public partial class CharacterDetails : VisualElement
{
    [UxmlAttribute("character-name", "npc-name")]
    public string npcName { get; set; }

    [UxmlAttribute("character-health", "health")]
    public float health { get; set; }
}

下面显示了 UXML 中的示例用法:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <CharacterDetails npc-name="Haydee" health="100" />
</ui:UXML>

覆盖UXML属性的行为

您可以覆盖自定义控件的 UXML 属性的 get 和 set 行为。这会将原始属性替换为 UI Builder 属性视图中的覆盖版本。要覆盖属性,请定义新属性并使用[UxmlAttribute("original-attribute-name"), new-attribute].

您可以使用此属性覆盖来自定义从子类继承的属性。例如,若要在 IntegerField 中强制执行值限制,请重写 value 属性并应用 Range 属性,如下所示:

using UnityEngine;
using UnityEngine.UIElements;

[UxmlElement]
public partial class MyCustomIntField : IntegerField
{
    [UxmlAttribute("value"), Range(0, 100)]
    private int valueOverride
    {
        get => this.value;
        set => this.value = value;
    }
}

在此示例中,MyCustomIntField 类继承自 IntegerField 并重写 value 属性。Range 属性将值限制为0100.

在 UI 构建器中添加 MyCustomIntField 时,覆盖的版本将替换 value 属性。这允许您在指定范围内设置值。

在 UI Builder 中添加属性装饰器

你可以在 UXML 属性字段上添加以下装饰器属性。添加装饰器属性时,相应的 UI 控件(例如Range,显示在 UI Builder 的检查器一个 Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑值。更多信息
请参阅术语表
面板:

以下示例在其属性字段上创建一个带有装饰器的自定义控件:

using UnityEngine.UIElements;
using UnityEngine;

[UxmlElement]
public partial class ExampleText : VisualElement
{
    [TextArea, UxmlAttribute]
    public string myText;

    [Header("My Header")]
    [Range(0, 100)]
    [UxmlAttribute]
    public int rangedInt;

    [Tooltip("My custom tooltip")]
    [Min(10)]
    [UxmlAttribute]
    public int minValue = 100;
}

UI Builder 显示带有装饰器的属性:

带有装饰器的属性
带有装饰器的属性

在 UI Builder 中添加自定义属性抽屉

您可以在 UI 生成器中的字段上添加自定义属性抽屉

以下示例使用自定义属性抽屉创建自定义控件:

using UnityEngine;
using UnityEngine.UIElements;

public class MyDrawerAttribute : PropertyAttribute { }

[UxmlElement]
public partial class MyDrawerExample : Button
{
    [UxmlAttribute]
    public Color myColor;

    [MyDrawer, UxmlAttribute]
    public string myText;
}

要访问其他序列化属性,请在名称前面加上serializedData.以下代码示例使用serializedData.myColor找到myColor属性:

using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;

[CustomPropertyDrawer(typeof(MyDrawerAttribute))]
public class MyDrawerAttributePropertyDrawer : PropertyDrawer
{
    public override VisualElement CreatePropertyGUI(SerializedProperty property)
    {
        var row = new VisualElement { style = { flexDirection = FlexDirection.Row } };
        var textField = new TextField("My Text") { style = { flexGrow = 1 } };
        var button = new Button { text = ":" };
        button.clicked += () => textField.value = "RESET";

        // Get the parent property
        var parentPropertyPath = property.propertyPath.Substring(0, property.propertyPath.LastIndexOf('.'));
        var parent = property.serializedObject.FindProperty(parentPropertyPath);

        var colorProp = parent.FindPropertyRelative("myColor");
        textField.TrackPropertyValue(colorProp, p =>
        {
            row.style.backgroundColor = p.colorValue;
        });

        row.style.backgroundColor = colorProp.colorValue;
        row.Add(textField);
        row.Add(button);
        textField.BindProperty(property);

        return row;
    }
}

自定义属性抽屉如下所示:

带有颜色选择器的自定义属性抽取盒
带有颜色选择器的自定义属性抽取盒

其他资源

为复杂数据类型定义自定义控件属性
将自定义控件绑定到数据