UxmlAttributeAttribute
класс в UnityEngine.UIElements
Выполнено в:UnityEngine.UIElementsModule
Описание
Заявляет, что поле или свойство связано с атрибутом UXML. Удобная перегрузка, сокращение для Query<T>.Build().First().
Вы можете использовать атрибут UxmlAttribute, чтобы объявить, что свойство или поле связано с атрибутом UXML. Когда элемент помечен атрибутом UxmlElement, соответствующий атрибут UxmlSerializedData класс формируется в частичном классе. Этот класс данных содержит SerializeField для каждого поля или свойства, помеченного атрибутом UxmlAttribute. Когда поле или свойство ассоциируется с атрибутом 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 name. В следующем примере создается пользовательский контроллер с настроенными именами атрибутов:
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 с предыдущим именем атрибута все еще могут быть загружены UI Builder, используйте аргумент 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>
Строки могут содержать запятые, закодированные как %2C в UXML. Когда вы создаете UXML напрямую, используйте кодированную форму %2C, чтобы запятые не были ошибочно приняты за разделители списков. Следующий код C# определяет пользовательский контроллер, MyStringListElement, с атрибутом my-string, который представляет Список строк.
using System.Collections.Generic; using UnityEngine.UIElements;
[UxmlElement] public partial class MyStringListElement : VisualElement { [UxmlAttribute("my-strings")] public List<string> strings; }
В следующем примере UXML используется %2C для разделения слов в списке строк:
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<MyStringListElement my-strings="One,Two%2CThree%2CFour,Five,Six%2CSeven and Eight" />
</ui:UXML>
Если у атрибута такое же имя UXML, как у атрибута дочернего класса, он имеет приоритет, переопределяет то поле и отображается в инспекторе вместо него. Благодаря этому поле можно заменить полем другого типа или собственным свойством. В следующем примере показано, как заменить значение IntegerField на SliderField.
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; } }
Свойства
| Свойство | Описание |
|---|---|
| name | Предоставляет пользовательское имя UXML для атрибута. |
| obsoleteNames | Обеспечивает поддержку устаревших имен атрибутов UXML. |
Конструкторы
| Конструктор | Описание |
|---|---|
| UxmlAttributeAttribute | Заявляет, что поле или свойство связано с атрибутом UXML. |