包含此页的版本:
不含此页的版本:
您可以使用属性转换器和 UxmlObject 来支持自定义控件的复杂数据类型属性。
属性转换器将 UxmlAttribute 类型与字符串进行转换。它为常见类型提供了一组内置转换器,例如int,float,bool,string和Vector2.对于复杂的数据类型,例如列表或自定义类,您需要创建自定义转换器。
以下 C# 代码示例创建一个名为Person以及一个名为Department.这Department类包含一个Person字段和Person对象。
using System;
using System.Collections.Generic;
using UnityEngine.UIElements;
namespace AttributeConverterExample
{
[Serializable]
public class Person
{
public string name;
public int age;
public string nationality;
}
[UxmlElement]
public partial class Department : VisualElement
{
[UxmlAttribute]
public Person manager;
[UxmlAttribute]
public List<Person> employees;
}
}
如果在 UI Builder 中编辑自定义控件,则会收到以下错误消息:
[UxmlElement] 'Department' has a [UxmlAttribute] 'manager' of an unknown type 'Person'. To fix this error, define a custom UxmlAttributeConverter<Person>.
要解决此问题,请为Person继承自UxmlAttributeConverter<Person>并实现ToString和FromString将Person对象与字符串的对象。以下示例为Person类:
using UnityEditor.UIElements;
namespace AttributeConverterExample
{
public class PersonConverter : UxmlAttributeConverter<Person>
{
const char k_Separator = ':';
public override string ToString(Person value)
{
return $"{value.name}{k_Separator}{value.age}{k_Separator}{value.nationality}";
}
public override Person FromString(string value)
{
var person = new Person();
var split = value.Split(k_Separator);
if (split.Length == 3)
{
person.name = split[0];
person.age = int.Parse(split[1]);
person.nationality = split[2];
}
return person;
}
}
}
转换器将这三个值组合成一个字符串格式,模式为[name]:[age]:[nationality].这FromString方法将字符串拆分为三个值,并将它们分配给Person对象。
下面显示了Department元素:
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<AttributeConverterExample.Department name="Dunder Mifflin" manager="Michael Scott:58:USA" employees="Dwight Schrute:53:USA,Jim Halpert:44:USA" />
</ui:UXML>
使用属性转换器时,随着数据类型变得更加复杂或处理大量列表时,生成的字符串会迅速变得复杂且笨拙。为了简化这一点,您可以使用UxmlObjects.
UxmlObjects是从 UXML 实例化的包含 UXML 属性的类。
了解如何使用UxmlObjects,取上一个Person和Department类示例,将它们转换为UxmlObjects如以下示例所示:
using System;
using System.Collections.Generic;
using UnityEngine.UIElements;
namespace UxmlObjectExample
{
[UxmlObject]
public partial class Person
{
[UxmlAttribute]
public string name;
[UxmlAttribute]
public int age;
[UxmlAttribute]
public string nationality;
}
[UxmlElement]
public partial class Department : VisualElement
{
[UxmlObjectReference("manager")]
public Person manager;
[UxmlObjectReference("employees")]
public List<Person> employees;
}
}
这Personclass 现在类似于自定义元素,并且使用UxmlAttributefor 属性声明,并引入 UxmlObject 属性来表示其状态为UxmlObject.
而不是使用UxmlAttribute为UxmlObject字段,此示例使用 UxmlObjectReference 将name.该名称指定了UxmlObject.
以前,所有UxmlObjects被存储为元素的直接子级,这会导致当多个UxmlObject场地存在。很难区分是哪一个UxmlObjects属于哪个领域。
这UxmlObjectReference属性通过为UxmlObject.此名称对应于 UXML 标签名称。在前面的示例中,manager和employees字段属于Person类。这UxmlObjectReference属性确保Personclass 被正确地分配给manager和employees领域。
下面显示了 UXML 文件中的用法示例:
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<UxmlObjectExample.Department name="Department One">
<manager>
<UxmlObjectExample.Person name="Manager One" age="58" nationality="Canadian">
</manager>
<employees>
<UxmlObjectExample.Person name="Person Two" age="53" nationality="Canadian">
<UxmlObjectExample.Person name="Person Three" age="44" nationality="Canadian">
</employees>
</UxmlObjectExample.Department>
</ui:UXML>
注意: UxmlObjectReferenceFields也适用于接口。但是,您只能分配UxmlObjects实现指定接口。有关使用接口的示例,请参阅 UxmlObjectReferenceAttribute。