您可以使用 SerializedObject 数据绑定系统绑定到序列化属性。这意味着您可以将视觉元素视觉树的一个节点,它实例化或派生自 C# VisualElement
类。您可以设置外观样式、定义行为并在屏幕上将其显示为 UI 的一部分。 更多信息
参见 术语表绑定到与序列化系统兼容的以下对象
ScriptableObject
类MonoBehaviour
类int
、bool
或 float
之类的原始 C# 类型。Vector3
、Color
或 Object
之类的原生 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# 脚本中设置绑定路径。
binding-path
属性。有关示例,请参阅在 UXML 中定义绑定路径。IBindable
接口设置bindingPath
。有关示例,请参阅使用绑定路径绑定。BindProperty()
您可以调用BindProperty()
将元素直接绑定到SerializedProperty
。
如果您已拥有 SerializedProperty
对象,并且尤其是在遍历SerializedObject
的属性以动态构建 UI 时,可以使用此方法。有关示例,请参阅无需绑定路径绑定。
您可以将视觉元素绑定到源对象中的嵌套属性。为此,请将元素的绑定路径与第一个祖先的绑定路径组合起来。将此方法与以下元素一起使用
BindableElement
TemplateContainer
(对应于 UXML 中的 <Instance>
标记)GroupBox
有关示例,请参阅绑定到嵌套属性。
您可以创建一个绑定,以便在绑定的序列化属性更改时接收回调。为此,请利用TrackPropertyValue()
扩展方法,该方法可用于任何 VisualElement
。这将注册一个回调,该回调在提供的 SerializedProperty
更改时执行。有关示例,请参阅序列化属性更改时接收回调。
您还可以创建一个绑定,以便在绑定的序列化对象的任何属性更改时接收回调。为此,请利用TrackSerializedObjectValue()
扩展方法,该方法可用于任何 VisualElement
。这将注册一个回调,该回调在提供的 SerializedProperty
更改时执行。有关示例,请参阅任何属性更改时接收回调。
您可以创建自定义元素并通过值绑定系统将其绑定到序列化属性。
要创建可绑定的自定义元素
BindableElement
继承元素或实现 IBinding
接口。INotifyValueChanged
接口。INotifyValueChanged
接口的 SetValueWithoutNotify()
方法。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()
来绑定它们。Bind()
或 BindProperty()
,无论元素添加到视觉树的时间如何。如果您调用 Bind()
或 BindProperty()
并同时绑定多个控件,请设置每个控件的绑定路径,然后在包含所有控件的最低级别父元素上调用 Bind()
。 Bind()
会绑定其自身调用的元素(如果该元素具有绑定路径),并递归绑定其所有子元素(如果它们具有绑定路径)。为了防止对性能产生负面影响,请勿使用 Bind()
方法多次绑定视觉元素。尝试以下示例以了解如何使用数据绑定进行编码