Unity3D :序列化对象数据绑定
推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生
序列化对象数据绑定
数据绑定将非 UI 对象的属性(例如 MonoBehavior
上的属性)与string
用户界面
对象,例如文本字段的属性。绑定是指属性与修改它的可视控件之间的链接。value
使用数据绑定同步属性和特定属性之间的值视觉元素
,因此当 UI 中的值发生更改时,无需编写事件处理程序。
注: 序列化对象数据绑定仅在编辑器中工作,在运行时无效。
序列化要求
只能绑定到序列化属性。这意味着只能将可视元素绑定到与序列化系统兼容的以下对象:
- 用户定义的
可脚本对象
类 - 用户定义的
单行为
类 - 原生 Unity 组件类型
- 原生 Unity 资源类型
- 基元 C# 类型,如、、等。
intboolfloat
- 本机 Unity 类型,例如 、 、 等。
Vector3ColorObject
值绑定
只能绑定实现 INotifyValueChanged
接口的可视元素的属性。例如,可以将 TextField.value
绑定到 ,但不能将 TextField.name
绑定到 .valuestringstring
您可以在对象和任何派生自 BindableElement
或实现 IBindable
接口的可视元素之间进行绑定。
创建绑定
若要创建绑定,请调用 Bind()
或 BindProperty()。
叫Bind()
您可以调用 Bind()
将元素绑定到 SerializedObject。在绑定元素之前,必须设置绑定路径并创建序列化对象。
如果您无法轻松访问绑定的 ,请使用此方法。有关示例,请参阅使用 C# 脚本创建绑定。SerializedProperty
Bind()
扩展方法使用指定的 bindingPath
属性设置可视元素的整个层次结构。可以对要绑定的层次结构的单个元素或父元素调用 Bind()
方法。例如,您可以在编辑器窗口上调用 Bind()。
这将绑定具有指定 bindingPath
属性的所有子元素。rootVisualElement
不要从 或 覆盖调用 Bind()。
这些重写在这些方法返回的可视元素上自动调用。Editor.CreateInspectorGUI()PropertyDrawer.CreatePropertyGUI()
叫Unbind()
Unbind()
方法停止对元素及其所有直接和间接子元素的值跟踪。通常,您不需要调用 Unbind(),
因为当用户关闭检查器或编辑器窗口时,跟踪会停止。如果必须在元素的生存期内将元素绑定到不同的目标,请调用 Unbind()。
如果在 C# 中通过调用其构造函数来构造检查器元素
,则在构造函数调用期间会发生绑定。如果要在构造 InspectorElement
后重新绑定它,则必须调用 Unbind(),
然后显式调用 Bind()
或让父级的绑定操作创建绑定。
设置绑定路径
如果调用 Bind()
来创建绑定,则必须将可视元素的绑定路径设置为要绑定到的对象的属性名称。
例如:
如果您有以下组件脚本:
using UnityEngine;
public class MyComp : MonoBehaviour
{
[SerializeField]
int m_Count;
}
要将可视元素绑定到 ,请将绑定路径设置为 。m_Countm_Count
- 如果要将可视元素绑定到游戏对象
的 name 属性,即 ,将绑定路径设置为 。m_Namem_Name
可以在 UI 生成器、UXML 或使用 C# 脚本中设置绑定路径:
- 在 UI 生成器中,在检查员
. - 在 UXML 中,设置可视元素的属性。有关示例,请参阅在 UXML 中定义绑定路径。
binding-path
- 在 C# 中,从
IBindable
接口设置bindingPath
。有关示例,请参阅使用绑定路径绑定。
叫BindProperty()
你可以调用 BindProperty()
将元素直接绑定到 SerializedProperty
。
如果已有对象,尤其是遍历序列化对象的
属性以动态生成 UI,请使用此方法。有关示例,请参阅不带绑定路径的绑定。SerializedProperty
将元素绑定到嵌套属性
可以将可视元素绑定到源对象中的嵌套属性。为此,请将元素的绑定路径与第一个祖先的绑定路径组合在一起。将此方法与以下元素一起使用:
BindableElement
TemplateContainer
(对应于UXML中的标签)<Instance>
GroupBox
有关示例,请参阅绑定到嵌套属性。
值更改时接收回调
可以创建绑定,以便在绑定序列化属性更改时接收回调。为此,请利用 TrackPropertyValue()
扩展方法,该方法可用于任何 .这将注册一个回调,该回调在提供的更改时执行。有关示例,请参阅序列化属性更改时接收回调。VisualElementSerializedProperty
还可以创建一个绑定,以便在绑定序列化对象的任何属性发生更改时接收回调。为此,请利用 TrackSerializedObjectValue()
扩展方法,该方法可用于任何 .这将注册一个回调,该回调在提供的更改时执行。有关示例,请参阅在任何属性更改时接收回调。VisualElementSerializedProperty
绑定自定义元素
可以创建自定义元素,并通过值绑定系统将它们绑定到序列化属性。
创建可绑定的自定义元素:
- 声明自定义元素。
- 从接口继承元素或实现接口。
BindableElementIBinding
- 实现接口。
INotifyValueChanged
- 将方法实现到接口。
SetValueWithoutNotify()INotifyValueChanged
- 实现接口的属性访问器。
valueINotifyValueChanged
有关示例,请参阅创建自定义控件并设置其样式。
编写自定义检查器时,不必像上面的编辑器窗口示例中那样将序列化对象显式绑定到可视化树。此步骤在方法完成后隐式完成。此自动绑定步骤仅在此时执行。如果将回调之外的字段添加到方法,则需要手动绑定该字段。否则,它可能无法呈现或生成未定义的视觉效果。CreateInspectorGUICreateInspectorGUI
最佳实践
根据您创建的 UI 类型,绑定会在不同时间发生。这称为绑定时间。
下表描述了控件的绑定时间:
条件 | 自动绑定时间(假设设置了绑定路径) |
---|---|
用 C 语言构造的检查器元素 # | 在构造函数调用期间 |
当这些方法返回时,位于 CreateInspectorGUI() 或 CreatePropertyGUI() 的返回值下的子元素
| 在 CreateInspectorGUI() 或 CreatePropertyGUI() 返回后
|
在父元素上调用 Bind( ) 或 BindProperty() 时位于元素下的子元素 | 在 Bind( ) 或 BindProperty() 调用期间 |
其他 | 没有自动绑定;必须手动绑定元素或其父元素之一 |
以下是创建有关绑定时间的绑定时的最佳做法:
- 如果创建自定义
编辑器
或自定义PropertyDrawer
,请设置元素的绑定路径,而不是对 可视化树
在CreateInspectorGUI()
或 的正文末尾。这些元素在CreateInspectorGUI() 或 CreatePropertyGUI()
返回后自动绑定。但是,如果在此点之后将任何元素添加到可视化树中,请调用Bind(
) 或BindProperty()
来绑定它们。CreatePropertyGUI()
- 如果创建任何其他类型的 UI,请调用
Bind()
或BindProperty(),
而不考虑将元素添加到可视化树的时间。如果调用Bind(
) 或 BindProperty() 并同时绑定多个控件,请设置每个控件的绑定路径,然后在包含所有控件的最低级别父元素上调用Bind()。
Bind()
绑定调用它的元素(如果它具有绑定路径),如果它们具有绑定路径,则递归绑定其所有子元素。若要防止对性能产生负面影响,请不要多次将可视元素与Bind()
方法绑定。
由3D建模学习工作室整理翻译,转载请注明出处!