Version: 6000.3
语言: 中文
SerializedObject 数据绑定
可绑定元素参考

SerializedObject 数据绑定简介

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

  • 用户定义ScriptableObject
  • 用户定义MonoBehaviour
  • 原生 Unity 组件类型
  • 原生 Unity 资产类型
  • 原始 C# 类型,例如int,boolfloat.
  • 原生 Unity 类型,例如Vector3,ColorObject.

值绑定

您只能绑定value实现INotifyValueChanged接口。例如,您可以绑定TextField.value设置为string,但不能绑定TextField.name设置为string.

可以在对象和派生自BindableElement或实现IBindable接口。

创建绑定

要创建绑定,请Bind()BindProperty().

Bind()

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

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

Bind()扩展方法设置具有指定bindingPath性能。您可以调用Bind()方法。例如,您可以调用Bind()rootVisualElement编辑器窗口的。这将所有子元素与指定的bindingPath性能。

不要打电话Bind()Editor.CreateInspectorGUI()PropertyDrawer.CreatePropertyGUI()覆盖。这些替代在这些方法返回的视觉元素上自动调用。

Unbind()

Unbind()方法停止对元素及其所有直接和间接子元素的值跟踪。一般来说,你不需要调用Unbind()因为当用户关闭“检查器”或“编辑器”窗口时,跟踪会停止。叫Unbind()如果必须在元素的生存期内绑定到不同的目标。

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

设置绑定路径

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

例如:

  • 如果您有以下组件脚本:

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

    将视觉元素绑定到m_Count,将绑定路径设置为m_Count.

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

你可以在UI Builder、UXML或C#脚本中设置绑定路径:

BindProperty()

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

如果您已经有一个SerializedProperty对象,特别是如果你遍历SerializedObject以动态构建 UI。有关示例,请参阅 没有绑定路径的绑定

将元素绑定到嵌套属性

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

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

值发生变化时接收回传

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

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

绑定自定义元素

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

要创建可绑定的自定义元素,请执行以下作:

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

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

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

绑定时间

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

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

条件 自动绑定时间(假设设置了绑定路径)
InspectorElement用 C 构建# 构造函数调用期间
返回值低于CreateInspectorGUI()CreatePropertyGUI()当这些方法返回 CreateInspectorGUI()CreatePropertyGUI()返回
在元素下Bind()BindProperty()在父元素上调用 Bind()BindProperty()
其他 无自动绑定;您必须手动绑定元素或其父元素之一

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

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

绑定到序列化属性支持字段

使用自动属性时,编译器会自动生成一个支持字段,其名称为<PropertyName>k__BackingField.此字段在代码中不显式可见,但可以在必要时引用,就像在绑定方案中一样。

例如,以下示例定义了 auto-propertySomeProp并将其序列化:

[field: SerializeField] 
public float SomeProp 
{ 
    get; 
    private set; 
}

编译器生成以下支持字段:

[SerializedField]
private float <SomeProp>k__BackingField;

public float SomeProp
{
    get => <SomeProp>k__BackingField;
    set => <SomeProp>k__BackingField = value;
}

绑定到<SomeProp>k__BackingField在 UXML 中,您必须转义,因为它们是为标记保留的。例如,将<>binding-path如下:

<editor:PropertyField name="some-prop" binding-path="&lt;SomeProp&gt;k__BackingField"/>

绑定示例

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

其他资源

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