版本: Unity 6 (6000.0)
语言英语
  • C#

UxmlObjectReferenceAttribute

UnityEngine.UIElements 中的类

/

实现于:UnityEngine.UIElementsModule

建议更改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们无法接受所有提交,但我们确实阅读了用户提出的每个建议更改,并在适用的情况下进行更新。

关闭

提交失败

由于某些原因,您的建议更改无法提交。请<a>稍后再试</a>。感谢您抽出时间帮助我们提高 Unity 文档的质量。

关闭

取消

描述

声明字段或属性与嵌套的 UXML 对象相关联。

您可以利用 UxmlObjectReferenceAttribute 指示属性或字段链接到一个或多个 UXML 对象。通过向类添加 UxmlObjectAttribute 属性,您可以声明一个 UXML 对象。您可以使用这些 UXML 对象将复杂数据与字段关联,超越单个 UxmlAttributeAttribute 的功能。字段类型必须是 UXML 对象或接口。当使用接口时,只有 UXML 对象类型对 UXML 序列化有效。

以下示例显示了 UxmlObjectReferenceAttribute 的常见用例。它使用该属性将 UXML 对象列表与字段或属性关联

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

[UxmlObject] public partial class Option { [UxmlAttribute] public string name { get; set; }

[UxmlAttribute] public bool bold { get; set; }

[UxmlAttribute] public Color color; }

[UxmlElement] public partial class MyColoredListField : VisualElement { private List<Option> m_Options; private PopupField<Option> m_PopupField;

[UxmlObjectReference("options")] public List<Option> options { get => m_Options; set { m_Options = value; m_PopupField.choices = m_Options; } }

public MyColoredListField() { m_PopupField = new PopupField<Option>(); Add(m_PopupField);

if (options != null) m_PopupField.choices = options;

m_PopupField.formatSelectedValueCallback = FormatItem; m_PopupField.formatListItemCallback = FormatItem; }

static string FormatItem(Option option) { if (option == null) return "";

var coloredString = $"<color=#{ColorUtility.ToHtmlStringRGB(option.color)}>{option.name}</color>";

if (option.bold) return $"<b>{coloredString}</b>"; return coloredString; } }

示例 UXML

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <MyColoredListField>
        <options>
            <Option name="Red" color="#FF0000FF" bold="true" />
            <Option name="Green" color="#00FF00FF" />
            <Option name="Blue" color="#0000FFFF" />
        </options>
    </MyColoredListField>
</ui:UXML>

您可以使用基本类型并将派生类型合并为 UXML 对象。以下示例自定义按钮以在单击时表现出不同的行为,例如显示标签或播放声音效果。

using UnityEngine;
using UnityEngine.UIElements;

[UxmlObject] public abstract partial class ButtonBehaviour { [UxmlAttribute] public string name { get; set; }

public abstract void OnClicked(Button button); }

[UxmlObject] public partial class CreateLabel : ButtonBehaviour { [UxmlAttribute] public string text { get; set; } = "I was clicked!";

public override void OnClicked(Button button) { var label = new Label(text); button.parent.Add(label); } }

[UxmlObject] public partial class PlaySound : ButtonBehaviour { [UxmlAttribute] public AudioClip sound { get; set; }

public override void OnClicked(Button button) { AudioSource.PlayClipAtPoint(sound, Vector3.zero); } }

[UxmlElement] public partial class ButtonWithClickBehaviourExample : Button { [UxmlObjectReference("clicked")] public ButtonBehaviour clickedBehaviour { get; set; }

public ButtonWithClickBehaviourExample() { clicked += OnClick; }

void OnClick() { clickedBehaviour?.OnClicked(this); } }

示例 UXML

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
    <ButtonWithClickBehaviourExample text="Play Sound">
        <clicked>
            <PlaySound sound="project://database/Assets/ClickedSound.wav" />
        </clicked>
    </ButtonWithClickBehaviourExample>
    <ButtonWithClickBehaviourExample text="Show Label">
        <clicked>
            <CreateLabel text="I was clicked!" />
        </clicked>
    </ButtonWithClickBehaviourExample>
</ui:UXML>

您还可以将接口与实现它的 UXML 对象一起使用。

using System.Collections.Generic;
using UnityEngine.UIElements;

public interface IMyUxmlObjectInterface { string name { get; set; } }

[UxmlObject] public partial class MyUxmlObject : IMyUxmlObjectInterface { [UxmlAttribute] public string name { get; set; } }

[UxmlElement] public partial class MyUxmlObjectElement : VisualElement { [UxmlObjectReference("item")] public IMyUxmlObjectInterface item { get; set; }

[UxmlObjectReference("item-list")] public List<IMyUxmlObjectInterface> itemList { get; set; } }

以下示例创建了多个具有自定义属性绘制器的 UxmlObjects 类型。它使用 UxmlObjects 来描述学校、老师和学生

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

/// <summary> /// The classes that a student can take. /// </summary> public enum Class { Maths, MathsAdvanced, Science, ScienceAdvanced, Psychology, Sociology, Economics, English, French, History, }

/// <summary> /// The base class contains the common properties for both students and teachers. /// </summary> [UxmlObject] public abstract partial class Person { [UxmlAttribute] public int Id { get; set; }

[UxmlAttribute] public string Name { get; set; } }

/// <summary> /// A student has a list of classes and a photo. /// </summary> [UxmlObject] public partial class Student : Person { [UxmlAttribute] public List<Class> Classes { get; set; }

[UxmlAttribute] public Texture2D Photo { get; set; } }

/// <summary> /// A teacher has a list of classes taught. /// </summary> [UxmlObject] public partial class Teacher : Person { [UxmlAttribute] public List<Class> ClassesTaught { get; set; } }

/// <summary> /// A school has a list of people which includes both students and teachers. /// </summary> [UxmlObject] public partial class School { [UxmlAttribute] public string Name { get; set; }

[UxmlAttribute] public int NextAvailableId;

[UxmlObjectReference("people")] public List<Person> People { get; set; } }

/// <summary> /// A school district has a list of schools. /// </summary> [UxmlElement] public partial class SchoolDistrict : VisualElement { [UxmlObjectReference("schools")] public List<School> Schools { get; set; } }

您可以使用自定义属性绘制器在 Inspector 中显示 UXML 对象。属性绘制器必须用于 UxmlObject 的 UxmlSerializedData 类型。例如,要为 UxmlObject Student 创建属性绘制器,绘制器必须用于 Studen.UxmlSerializedData 类型。

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

// Note: The custom property drawer must be for the serialized data type. [CustomPropertyDrawer(typeof(School.UxmlSerializedData))] public class SchoolPropertyDrawer : PropertyDrawer { SerializedProperty m_People; SerializedProperty m_NextAvailableId; ListView m_ListView;

int GetNextId() { var id = m_NextAvailableId.intValue; if (id == 0) id++;

m_NextAvailableId.intValue = id + 1; return id; }

public override VisualElement CreatePropertyGUI(SerializedProperty property) { var root = new VisualElement();

m_People = property.FindPropertyRelative("People"); m_NextAvailableId = property.FindPropertyRelative("NextAvailableId");

var name = new PropertyField(); name.BindProperty(property.FindPropertyRelative("Name")); root.Add(name);

m_ListView = new ListView { showAddRemoveFooter = true, showBorder = true, showBoundCollectionSize = false, showAlternatingRowBackgrounds = AlternatingRowBackground.All, overridingAddButtonBehavior = OnAddItem, reorderable = true, reorderMode = ListViewReorderMode.Animated, virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight, bindingPath = m_People.propertyPath, };

root.Add(m_ListView);

return root; }

void OnAddItem(BaseListView baseListView, Button button) { var menu = new GenericMenu(); menu.AddItem(new GUIContent("Student"), false, () => AddItem<Student>()); menu.AddItem(new GUIContent("Teacher"), false, () => AddItem<Teacher>()); menu.DropDown(button.worldBound); }

void AddItem<T>() where T : new() { m_People.InsertArrayElementAtIndex(m_People.arraySize); var person = m_People.GetArrayElementAtIndex(m_People.arraySize - 1); person.managedReferenceValue = UxmlSerializedDataCreator.CreateUxmlSerializedData(typeof(T)); person.FindPropertyRelative("Id").intValue = GetNextId(); m_People.serializedObject.ApplyModifiedProperties(); m_ListView.RefreshItem(m_People.arraySize - 1); } }

[CustomPropertyDrawer(typeof(Student.UxmlSerializedData))] public class StudentPropertyDrawer : PropertyDrawer { public override VisualElement CreatePropertyGUI(SerializedProperty property) { var id = property.FindPropertyRelative("Id").intValue; var photo = property.FindPropertyRelative("Photo").objectReferenceValue as Texture2D;

var root = new VisualElement { style = { backgroundColor = new Color(0, 0.2f, 0, 0.25f) } }; root.Add(new Label($"Student({id})") { style = { unityTextAlign = TextAnchor.MiddleCenter } }); var image = new Image { image = photo, style = { height = 100, width = 100 } }; root.Add(image);

var name = new PropertyField(); name.BindProperty(property.FindPropertyRelative("Name")); root.Add(name);

var photoField = new PropertyField(); photoField.BindProperty(property.FindPropertyRelative("Photo")); photoField.RegisterValueChangeCallback(evt => { image.image = property.FindPropertyRelative("Photo").objectReferenceValue as Texture2D; }); root.Add(photoField);

var course = new PropertyField(); course.BindProperty(property.FindPropertyRelative("Classes")); root.Add(course);

return root; } }

[CustomPropertyDrawer(typeof(Teacher.UxmlSerializedData))] public class TeacherPropertyDrawer : StudentPropertyDrawer { public override VisualElement CreatePropertyGUI(SerializedProperty property) { var id = property.FindPropertyRelative("Id").intValue; var root = new VisualElement { style = { backgroundColor = new Color(0, 0, 0.2f, 0.25f) } }; root.Add(new Label($"Teacher({id})") { style = {unityTextAlign = TextAnchor.MiddleCenter }});

var name = new PropertyField(); name.BindProperty(property.FindPropertyRelative("Name")); root.Add(name);

var classField = new PropertyField(); classField.BindProperty(property.FindPropertyRelative("ClassesTaught")); root.Add(classField);

return root; } }

示例 UXML

<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
    <SchoolDistrict>
        <schools>
            <School name="Herrington High School" next-available-id="6">
                <people>
                    <Teacher id="1" classes-taught="Science" name="Elizabeth Burke" />
                    <Teacher id="2" classes-taught="Maths" name="Coach Willis" />
                    <Student id="3" classes="Maths" name="Casey Connor" />
                    <Student id="4" classes="Maths,English,French,History,Sociology" name="Delilah Profitt" />
                    <Student id="5" classes="Maths,MathsAdvanced,Science,ScienceAdvanced" name=" Marybeth Louise Hutchinson" />
                </people>
            </School>        
            <School name="Shermer High School" next-available-id="9">
                <people>
                    <Teacher id="3" classes-taught="English" name="Ed Rooney" />
                    <Teacher id="4" name="Mr. Lorensax" classes-taught="Economics" />
                    <Teacher id="5" classes-taught="English" name="Mr. Knowlan" />
                    <Teacher id="6" classes-taught="History" name="Mr. Rickets" />
                    <Student id="1" classes="Maths,Science,English" name="Ferris Bueller" />
                    <Student id="7" classes="Maths,MathsAdvanced,Science,ScienceAdvanced,French" name="Cameron Frye" />
                    <Student id="8" classes="Sociology,Economics,Phycology" name="Sloan Peterson" />
                </people>
            </School>
            <School name="Sunnydale High School" next-available-id="6">
                <people>
                    <Teacher id="1" classes-taught="Science,ScienceAdvanced" name="Grace Newman" />
                    <Teacher id="2" classes-taught="Science" name="Dr. Gregory" />
                    <Student id="3" classes="Maths" name=" James Stanley" photo="project://database/Assets/james-class-photo.jpg" />
                    <Student id="4" classes="Maths,English,French,History,Sociology" name="Buffy Summers" photo="project://database/Assets/buffy-class-photo.jpg" />
                    <Student id="5" classes="Maths,MathsAdvanced,Science,ScienceAdvanced" name="Willow Rosenberg" photo="project://database/Assets/willow-class-photo.jpg" />
                </people>
            </School>
        </schools>
    </SchoolDistrict>
</ui:UXML>

属性

nameUXML 对象序列化到的嵌套 UXML 元素的名称。注意:空值或空字符串会导致对象序列化到根节点。
types在 UI Builder 中,当将 UXML 对象添加到具有多个派生类型的字段时,会显示一个下拉列表,其中包含可添加到字段的可用类型的选择。默认情况下,此列表包含从 UXML 对象类型继承的所有类型。您可以使用参数指定要显示的已接受类型的列表,而不是显示所有可用类型

构造函数

UxmlObjectReferenceAttribute声明字段或属性与嵌套的 UXML 对象相关联。