版本:Unity 6 (6000.0)
语言:English
SerializedObject 数据绑定
可绑定元素参考

SerializedObject 数据绑定简介

您可以使用 SerializedObject 数据绑定系统绑定到序列化属性。这意味着您可以将视觉元素视觉树的一个节点,它实例化或派生自 C# VisualElement 类。您可以设置外观样式、定义行为并在屏幕上将其显示为 UI 的一部分。 更多信息
参见 术语表
绑定到与序列化系统兼容的以下对象

  • 用户定义的ScriptableObject
  • 用户定义的MonoBehaviour
  • 原生 Unity 组件类型
  • 原生 Unity 资源类型
  • 诸如 intboolfloat 之类的原始 C# 类型。
  • 诸如 Vector3ColorObject 之类的原生 Unity 类型。

值绑定

您只能绑定实现INotifyValueChanged 接口的视觉元素的 value 属性。例如,您可以将TextField.value 绑定到 string,但不能将TextField.name 绑定到 string

您可以在对象与任何派生自BindableElement 或实现IBindable 接口的视觉元素之间进行绑定。

创建绑定

要创建绑定,请调用 Bind()BindProperty()

调用 Bind()

您可以调用Bind() 将元素绑定到SerializedObject。在绑定元素之前,必须设置绑定路径并创建 SerializedObject。

如果您无法轻松访问绑定的 SerializedProperty,则可以使用此方法。有关示例,请参阅使用 C# 脚本创建绑定

Bind() 扩展方法使用指定的bindingPath 属性设置整个视觉元素层次结构。您可以在要绑定的单个元素或层次结构的父级上调用Bind() 方法。例如,您可以在编辑器窗口的 rootVisualElement 上调用Bind()。这将绑定所有具有指定bindingPath 属性的子元素。

不要从 Editor.CreateInspectorGUI()PropertyDrawer.CreatePropertyGUI() 覆盖中调用Bind()。这些覆盖会自动在这些方法返回的视觉元素上调用。

调用 Unbind()

Unbind() 方法会停止元素及其所有直接和间接子元素的值跟踪。通常,您不需要调用Unbind(),因为当用户关闭检查器或编辑器窗口时,跟踪会停止。如果必须在元素的生命周期中将其绑定到不同的目标,请调用Unbind()

如果您通过调用其构造函数在 C# 中构造InspectorElement,则绑定会在构造函数调用期间发生。如果您希望在构造InspectorElement 后重新绑定它,则必须调用Unbind(),然后显式调用Bind() 或让来自父级的绑定操作创建绑定。

设置绑定路径

如果您调用Bind() 来创建绑定,则必须将视觉元素的绑定路径设置为要绑定到的对象的属性名称。

例如

  • 如果您有以下组件脚本

    using UnityEngine;
    
    public class MyComp : MonoBehaviour
    {
        [SerializeField]
        int m_Count;
    }
    

    要将您的视觉元素绑定到 m_Count,请将绑定路径设置为 m_Count

  • 如果要将视觉元素绑定到游戏对象Unity 场景中的基本对象,可以表示角色、道具、场景、摄像机、路径点等等。游戏对象的功能由附加到它的组件定义。 更多信息
    参见 术语表
    的名称属性(即 m_Name),请将绑定路径设置为 m_Name

您可以在UI(用户界面) 允许用户与您的应用程序交互。Unity 目前支持三种 UI 系统。 更多信息
参见 术语表
构建器、UXML 或使用 C# 脚本中设置绑定路径。

调用 BindProperty()

您可以调用BindProperty() 将元素直接绑定到SerializedProperty

如果您已拥有 SerializedProperty 对象,并且尤其是在遍历SerializedObject 的属性以动态构建 UI 时,可以使用此方法。有关示例,请参阅无需绑定路径绑定

将元素绑定到嵌套属性

您可以将视觉元素绑定到源对象中的嵌套属性。为此,请将元素的绑定路径与第一个祖先的绑定路径组合起来。将此方法与以下元素一起使用

有关示例,请参阅绑定到嵌套属性

值更改时接收回调

您可以创建一个绑定,以便在绑定的序列化属性更改时接收回调。为此,请利用TrackPropertyValue() 扩展方法,该方法可用于任何 VisualElement。这将注册一个回调,该回调在提供的 SerializedProperty 更改时执行。有关示例,请参阅序列化属性更改时接收回调

您还可以创建一个绑定,以便在绑定的序列化对象的任何属性更改时接收回调。为此,请利用TrackSerializedObjectValue() 扩展方法,该方法可用于任何 VisualElement。这将注册一个回调,该回调在提供的 SerializedProperty 更改时执行。有关示例,请参阅任何属性更改时接收回调

绑定自定义元素

您可以创建自定义元素并通过值绑定系统将其绑定到序列化属性。

要创建可绑定的自定义元素

  1. 声明自定义元素.
  2. BindableElement 继承元素或实现 IBinding 接口。
  3. 实现 INotifyValueChanged 接口。
  4. 实现 INotifyValueChanged 接口的 SetValueWithoutNotify() 方法。
  5. 实现 INotifyValueChanged 接口的 value 属性访问器。

有关示例,请参阅创建和设置自定义控件的样式

注意:您不能将自定义数据类型直接绑定到自定义元素,因为绑定系统仅允许您将元素绑定到 enum 的 SerializedPropertyType 支持的类型。这意味着您不能定义类或结构(例如,名为 MyStruct 的结构),并将其绑定到实现 INotifyValueChanged<MyStruct> 的元素。但是,您可以绑定到自定义数据类型的可序列化嵌套属性。这包括多态序列化(当字段使用[SerializeReference] 属性时)。有关示例,请参阅将自定义控件绑定到自定义数据类型

最佳实践

根据您创建的 UI 类型,绑定会在不同的时间发生。这称为绑定时间。

下表描述了控件的绑定时间

条件 自动绑定时间(假设已设置绑定路径)
在 C# 中构造的 InspectorElement 构造函数调用期间
当这些方法返回时,位于CreateInspectorGUI()CreatePropertyGUI() 的返回值下的子元素 CreateInspectorGUI()CreatePropertyGUI() 返回之后
当在父元素上调用Bind()BindProperty() 时,位于元素下的子元素 Bind()BindProperty() 调用期间
其他 没有自动绑定;您必须手动绑定元素或其父级之一

以下是在创建绑定时有关绑定时间的最佳实践

  • 如果您创建自定义的 Editor 或自定义的 PropertyDrawer,请设置元素的绑定路径,而不是在 视觉树一个由轻量级节点组成的对象图,它包含窗口或面板中的所有元素。它定义了您使用 UI 工具包构建的每个 UI。
    参见 词汇表
    中的任何视觉元素上调用 Bind()BindProperty(),这些元素位于 CreateInspectorGUI()CreatePropertyGUI() 函数体的末尾。这些元素会在 CreateInspectorGUI()CreatePropertyGUI() 返回后自动绑定。但是,如果您在该点之后向视觉树添加任何元素,请调用 Bind()BindProperty() 来绑定它们。
  • 如果您创建任何其他类型的 UI,请调用 Bind()BindProperty(),无论元素添加到视觉树的时间如何。如果您调用 Bind()BindProperty() 并同时绑定多个控件,请设置每个控件的绑定路径,然后在包含所有控件的最低级别父元素上调用 Bind()Bind() 会绑定其自身调用的元素(如果该元素具有绑定路径),并递归绑定其所有子元素(如果它们具有绑定路径)。为了防止对性能产生负面影响,请勿使用 Bind() 方法多次绑定视觉元素。

绑定示例

尝试以下示例以了解如何使用数据绑定进行编码

其他资源

SerializedObject 数据绑定
可绑定元素参考