Version: Unity 6.0 (6000.0)
语言 : 中文
自定义控件
Configure the custom control name and visibility in UI Builder

创建自定义控件

良好的自定义控件是抽象又独立的,并且会重复出现。

滑动开关 (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 属性。

初始化自定义控件

自定义控件继承自 VisualElementVisualElement 不受游戏对象生命周期的约束,不会接收以下任何回调:

  • 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 可以像内置控件一样自定义控件的外观。还可以创建 USS 自定义属性来设置自定义控件的样式。

注意:UI Builder 中的 Inspector 窗口不显示 USS 自定义属性。要编辑 USS 自定义属性,请使用文本编辑器直接编辑 USS 文件。

要在 C# 中与自定义控件的自定义 USS 属性交互,请使用 CustomStyleProperty 结构和 CustomStylesResolvedEvent 事件。

CustomStyleProperty 描述了从样式表中读取的属性的名称和类型。

UI 工具包为直接接收自定义 USS 属性的任何元素分发 CustomStylesResolvedEvent。对于规则包含自定义属性值的选择器,它会为选择器匹配的任何元素分发事件。UI 工具包不会为继承该值的元素分发事件。事件包含对 ICustomStyle 对象的引用。必须使用其 TryGetValue() 方法来读取 CustomStyleProperty 的有效值。此方法为不同类型的 CustomStyleProperty 提供了重载。

有关带有自定义控件示例的自定义样式,请参阅为自定义控件创建自定义样式

注意:无法为自定义样式属性定义过渡。

自定义控件的处理事件

有关如何为自定义控件处理事件的详细信息,请参阅处理事件

注意

  • Unity 会将键盘事件派发到当前的焦点元素上。要处理自定义控件的键盘事件,请设置与 focus 相关的属性。
  • 要处理触摸和鼠标输入事件,请在构造函数中注册相关事件类型的回调,例如指针事件鼠标事件

最佳实践与提示

  • 将自定义控件表示的属性及其行为的其他功能方面公开为 UXML 属性,并将影响自定义控件外观的属性公开为 USS 属性。

  • 使用唯一、简短和可读的命名空间,以避免与其他元素的名称冲突。

  • 保持 UXML 属性的原始性。可以在 UXML 中指定的数据仅限于一组原始数据类型。UXML 不支持复杂的数据结构或集合。在运行时通过 C# 脚本或数据绑定将复杂数据传递给自定义控件,而不是在 UXML 中。

  • 在 C# 中,将 USS 类或名称公开为常量。这允许使用 UQuery 按类或名称查找元素。

  • 对 USS 类采用 BEM 标准。这允许使用类列表选择器寻址每个元素。

  • 使用静态回调可以减少内存占用。注册要用作回调的实例方法时,可能会创建不必要的分配。为避免分配,请使用调用常规 C# 静态方法的匿名静态 lambda 函数。可以通过 EventBase.currentTarget 属性检索当前元素的上下文。

  • 通过自定义控件的 generateVisualContent 回调渲染自定义几何体。有关渲染部分填充圆的用法示例,请参阅 RadialProgress 示例

  • 自定义控件很方便。但是,用以下方法也可以实现相同的结果:

    • 通过现有元素组装 UI,并更改其样式和属性。
    • 使用 UXML 模板。使用常规的 C# MonoBehaviour 来添加与包含您的 UI 的特定 UI 文档相关的逻辑。(要了解如何使用 MonoBehaviour 来控制 UI 文档中的 UI,请参阅创建第一个运行时 UI。)为实现封装,请在 MonoBehaviour 中创建属性和方法,在内部使用 UQuery 获取 VisualElement 并操作其属性。

其他资源

自定义控件
Configure the custom control name and visibility in UI Builder