声明字段或属性与 UXML 属性相关联。
您可以使用 UxmlAttribute 属性来声明属性或字段与 UXML 属性相关联。当元素被标记为 UxmlElement 属性时,将在部分类中生成一个相应的 UxmlSerializedData 类。此数据类包含每个用 UxmlAttribute 属性标记的字段或属性的 SerializeField。当字段或属性与 UXML 属性相关联时,其所有属性都会被转移到序列化版本。这允许支持自定义属性绘制器和装饰器属性,例如 HeaderAttribute、TextAreaAttribute、RangeAttribute、TooltipAttribute 等等。
以下示例创建了一个具有自定义属性的自定义控件
using UnityEngine.UIElements;
namespace Example { [UxmlElement] public partial class MyElement : VisualElement { [UxmlAttribute] public string myStringValue { get; set; }
[UxmlAttribute] public float myFloatValue { get; set; }
[UxmlAttribute] public int myIntValue { get; set; }
[UxmlAttribute] public UsageHints myEnumValue { get; set; } } }
Unity 对象也可以是 UxmlAttributes,并且在序列化为 UXML 时将包含对资产文件的引用。以下示例创建了一个具有自定义属性的自定义控件。属性类型为 UXML 模板和纹理
using UnityEngine; using UnityEngine.UIElements;
[UxmlElement] public partial class CustomElement : VisualElement { [UxmlAttribute] public VisualTreeAsset myTemplate { get; set; }
[UxmlAttribute] public Texture2D Texture2D { get; set; } }
默认情况下,在解析属性名称时,字段或属性名称将拆分为由连字符连接的小写单词。名称中的原始大写字符用于表示应在何处拆分名称。例如,如果属性名称是 myIntValue
,则相应的属性名称将是 my-int-value
。您可以通过 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>
如果您更改了属性的名称,并希望确保仍可以由 UI Builder 加载具有先前属性名称的 UXML 文件,请使用 obsoleteNames
参数。此参数匹配 UXML 中的属性,以便在序列化期间应用于属性。UI Builder 在加载 UXML 文件时使用新名称。以下示例创建了一个具有使用过时属性名称的自定义属性的自定义控件
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>
创建每个 SerializeField 时,所有属性都会被复制。这使您可以在 UI Builder 中对字段使用装饰器和自定义属性绘制器。以下示例使用一个在其属性字段上具有装饰器的自定义控件
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 使用装饰器显示属性
以下示例创建了一个具有自定义属性绘制器的自定义控件
using UnityEngine; using UnityEngine.UIElements;
public class MyDrawerAttribute : PropertyAttribute { }
[UxmlElement] public partial class MyDrawerExample : Button { [UxmlAttribute] public Color myColor;
[MyDrawer, UxmlAttribute] public string myText; }
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; } }
您可以在 UXML 中使用结构或类实例,甚至可以使用结构或类实例列表。但是,它们必须可转换为字符串和从字符串转换,并且您必须声明一个 UxmlAttributeConverter<T0> 来支持此转换。在列表中使用该类时,确保其字符串表示形式不包含任何逗号(“,”),因为此字符由列表用于分隔项目。有关支持更复杂数据的字段示例,请参阅 UxmlObjectReferenceAttribute。以下示例展示了类实例如何支持属性和列表
using System; using System.Collections.Generic; using UnityEngine.UIElements;
[Serializable] public class MyClassWithData { public int myInt; public float myFloat; }
[UxmlElement] public partial class MyElementWithData : VisualElement { [UxmlAttribute] public MyClassWithData someData;
[UxmlAttribute] public List<MyClassWithData> lotsOfData; }
using System; using System.Globalization; using UnityEditor.UIElements;
public class MyClassWithDataConverter : UxmlAttributeConverter<MyClassWithData> { public override MyClassWithData FromString(string value) { // Split using a | so that comma (,) can be used by the list. var split = value.Split('|');
return new MyClassWithData { myInt = int.Parse(split[0]), myFloat = float.Parse(split[1], CultureInfo.InvariantCulture) }; }
public override string ToString(MyClassWithData value) => FormattableString.Invariant($"{value.myInt}|{value.myFloat}"); }
<ui:UXML xmlns:ui="UnityEngine.UIElements"> <MyElementWithData some-data="1|2.3" lots-of-data="1|2,3|4,5|6" /> </ui:UXML>
当属性与子类属性共享相同的 UXML 名称时,它将优先于该字段并覆盖该字段,并在检查器中显示。使用此功能,您可以用不同类型或自定义属性替换字段。以下示例演示了如何用 SliderField 替换 IntegerField 值。
using UnityEngine.UIElements; using UnityEngine;
public class MyOverrideDrawerAttribute : PropertyAttribute { }
[UxmlElement] public partial class IntFieldWithCustomPropertyDrawer : IntegerField { // Override the value property to use the custom drawer [UxmlAttribute("value"), MyOverrideDrawer] internal int myOverrideValue { get => this.value; set => this.value = value; } }
using UnityEditor; using UnityEditor.UIElements; using UnityEngine.UIElements;
[CustomPropertyDrawer(typeof(MyOverrideDrawerAttribute))] public class MyOverrideDrawerAttributePropertyDrawer : PropertyDrawer { public override VisualElement CreatePropertyGUI(SerializedProperty property) { var field = new SliderInt(0, 100) { label = "Value" }; field.BindProperty(property); return field; } }
UxmlAttributeAttribute | 声明字段或属性与 UXML 属性相关联。 |