良好的自定义控件是抽象又独立的,并且会重复出现。
滑动开关 (Slide Toggle)是自定义控件的一个良好示例:
应用程序的菜单栏不是自定义控件的好示例:
创建自定义控件后,可使用 USS 对其进行样式设置,并通过 C# 添加处理事件的逻辑。
要创建自定义控件,请执行以下操作:
UxmlElement 属性添加到自定义控件类定义中。VisualElement 或其派生类之一继承它。例如:
using UnityEngine;
using UnityEngine.UIElements;
[UxmlElement]
public partial class ExampleElement : VisualElement {}
创建自定义控件后,可以在 UXML 和__ UI__(即用户界面,User Interface)让用户能够与您的应用程序进行交互。Unity 目前支持三种 UI 系统。更多信息
See in Glossary Builder 中使用它们。
以下 UXML 文档示例使用了自定义控件:
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ExampleElement />
</ui:UXML>
默认情况下,自定义控件显示在 UI Builder 的 Library 选项卡中。如果要在 Library 选项卡中隐藏此属性,请添加 HideInInspector 属性。
自定义控件继承自 VisualElement。VisualElement 不受游戏对象生命周期的约束,不会接收以下任何回调:
Awake()OnEnable()OnDisable()OnDestroy()您可以在自定义控件的构造函数中初始化该控件。但是,如果应用程序需要,可以延迟初始化,直到将自定义控件添加到 UI 中。为此,请为 AttachToPanelEvent 注册回调。要检测自定义控件是否已从 UI 中删除,请使用 DetachFromPanelEvent 回调。
public CustomControl()
{
var myCustomElement = rootVisualElement.Q(className: "my-custom-element");
myCustomElement.RegisterCallback<AttachToPanelEvent>(e =>
{ /* do something here when element is added to UI */ });
myCustomElement.RegisterCallback<DetachFromPanelEvent>(e =>
{ /* do something here when element is removed from UI */ });
}
UI 工具包为所有元素分发这两个事件,不需要自定义 VisualElement 子类。更多信息,请参阅面板事件。
使用 USS 可以像内置控件一样自定义控件的外观。还可以创建 USS 自定义属性来设置自定义控件的样式。
注意:UI Builder 中的 Inspector 窗口不显示 USS 自定义属性。要编辑 USS 自定义属性,请使用文本编辑器直接编辑 USS 文件。
要在 C# 中与自定义控件的自定义 USS 属性交互,请使用 CustomStyleProperty 结构和 CustomStylesResolvedEvent 事件。
CustomStyleProperty 描述了从样式表中读取的属性的名称和类型。
UI 工具包为直接接收自定义 USS 属性的任何元素分发 CustomStylesResolvedEvent。对于规则包含自定义属性值的选择器,它会为选择器匹配的任何元素分发事件。UI 工具包不会为继承该值的元素分发事件。事件包含对 ICustomStyle 对象的引用。必须使用其 TryGetValue() 方法来读取 CustomStyleProperty 的有效值。此方法为不同类型的 CustomStyleProperty 提供了重载。
有关带有自定义控件示例的自定义样式,请参阅为自定义控件创建自定义样式。
注意:无法为自定义样式属性定义过渡。
有关如何为自定义控件处理事件的详细信息,请参阅处理事件。
注意:
focus 相关的属性。将自定义控件表示的属性及其行为的其他功能方面公开为 UXML 属性,并将影响自定义控件外观的属性公开为 USS 属性。
使用唯一、简短和可读的命名空间,以避免与其他元素的名称冲突。
保持 UXML 属性的原始性。可以在 UXML 中指定的数据仅限于一组原始数据类型。UXML 不支持复杂的数据结构或集合。在运行时通过 C# 脚本或数据绑定将复杂数据传递给自定义控件,而不是在 UXML 中。
在 C# 中,将 USS 类或名称公开为常量。这允许使用 UQuery 按类或名称查找元素。
对 USS 类采用 BEM 标准。这允许使用类列表选择器寻址每个元素。
使用静态回调可以减少内存占用。注册要用作回调的实例方法时,可能会创建不必要的分配。为避免分配,请使用调用常规 C# 静态方法的匿名静态 lambda 函数。可以通过 EventBase.currentTarget 属性检索当前元素的上下文。
通过自定义控件的 generateVisualContent 回调渲染自定义几何体。有关渲染部分填充圆的用法示例,请参阅 RadialProgress 示例。
自定义控件很方便。但是,用以下方法也可以实现相同的结果:
MonoBehaviour 来添加与包含您的 UI 的特定 UI 文档相关的逻辑。(要了解如何使用 MonoBehaviour 来控制 UI 文档中的 UI,请参阅创建第一个运行时 UI。)为实现封装,请在 MonoBehaviour 中创建属性和方法,在内部使用 UQuery 获取 VisualElement 并操作其属性。