绑定的目的是将对象内的属性同步到可见的 UI。 _绑定_是指属性和对属性进行修改的可视化控件之间的链接。
绑定是在对象和任何从 BindableElement 派生的或实现 IBindable 接口的 UIElement 之间完成。
从 UnityEditor.UIElements
命名空间中:
基类:
控件:
从 UnityEngine.UIElements
命名空间中:
基类
控件
进行绑定的方法是使用上面列出的命名空间之一中的控件,同时执行以下步骤。
以下代码片段显示了如何使用 C# 代码创建绑定。要使用此代码片段,请将本示例作为 C# 文件保存在项目的 Editor 文件夹中。将该 C# 文件命名为 SimpleBindingExample.cs
。
SimpleBindingExample.cs
的内容:
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UIElementsExamples
{
public class SimpleBindingExample : EditorWindow
{
TextField m_ObjectNameBinding;
[MenuItem("Window/UIElementsExamples/Simple Binding Example")]
public static void ShowDefaultWindow()
{
var wnd = GetWindow<SimpleBindingExample>();
wnd.titleContent = new GUIContent("Simple Binding");
}
public void OnEnable()
{
var root = this.rootVisualElement;
m_ObjectNameBinding = new TextField("Object Name Binding");
m_ObjectNameBinding.bindingPath = "m_Name";
root.Add(m_ObjectNameBinding);
OnSelectionChange();
}
public void OnSelectionChange()
{
GameObject selectedObject = Selection.activeObject as GameObject;
if (selectedObject != null)
{
// 创建序列化对象
SerializedObject so = new SerializedObject(selectedObject);
// 将其绑定到层级视图的根目录。它将找到要绑定的正确对象...
rootVisualElement.Bind(so);
// ... 或者,也可以将其绑定到 TextField 本身。
// m_ObjectNameBinding.Bind(so);
}
else
{
// 取消对象与实际视觉元素的绑定
rootVisualElement.Unbind();
// m_ObjectNameBinding.Unbind();
// 删除绑定后,清除 TextField
m_ObjectNameBinding.value = "";
}
}
}
}
在 Unity 中,选择 Window > UIElementsExamples > Simple Binding Example。您可以使用此窗口在场景中选择任何游戏对象,并使用显示的 TextField 修改游戏对象的名称。
本节说明如何通过 UXML 层次视图设置来使用绑定。
在 UXML 中,属性 binding-path
在 TextField 控件中进行定义。就是这个属性会将控件绑定到对象的有效属性。
SimpleBindingExample.uxml
的内容:
<UXML xmlns:ui="UnityEngine.UIElements">
<ui:VisualElement name="top-element">
<ui:Label name="top-label" text="UXML-Defined Simple Binding"/>
<ui:TextField name="GameObjectName" label="Name" text="" binding-path="m_Name"/>
</ui:VisualElement>
</UXML>
SimpleBindingExample.cs
的内容:
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UIElementsExamples
{
public class SimpleBindingExampleUXML : EditorWindow
{
[MenuItem("Window/UIElementsExamples/Simple Binding Example UXML")]
public static void ShowDefaultWindow()
{
var wnd = GetWindow<SimpleBindingExampleUXML>();
wnd.titleContent = new GUIContent("Simple Binding UXML");
}
public void OnEnable()
{
var root = this.rootVisualElement;
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/SimpleBindingExample.uxml");
visualTree.CloneTree(root);
OnSelectionChange();
}
public void OnSelectionChange()
{
GameObject selectedObject = Selection.activeObject as GameObject;
if (selectedObject != null)
{
// 创建序列化对象
SerializedObject so = new SerializedObject(selectedObject);
// 将其绑定到层级视图的根目录。它将找到要绑定的正确对象...
rootVisualElement.Bind(so);
}
else
{
// 取消对象与实际视觉元素的绑定
rootVisualElement.Unbind();
// 删除绑定后,清除 TextField
//(如果 Q() 返回 null,此代码不安全)
rootVisualElement.Q<TextField>("GameObjectName").value = "";
}
}
}
}
InspectorElement
是用于特定类型 Unity 对象的 Inspector 的 UIElement 对应元素。使用 InspectorElement
来检查对象具有以下优点:
在 Assets/Editor/SimpleBindingExample.cs
下可以找到另一个简单的绑定示例,提供了用法示例和过程概述。
Assets/Editor/SimpleBindingExample.cs
的内容:
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
namespace UIElementsExamples
{
public class SimpleBindingExampleUXML : EditorWindow
{
[MenuItem("Window/UIElementsExamples/Simple Binding Example UXML")]
public static void ShowDefaultWindow()
{
var wnd = GetWindow<SimpleBindingExampleUXML>();
wnd.titleContent = new GUIContent("Simple Binding UXML");
}
TankScript m_Tank;
public void OnEnable()
{
m_Tank = GameObject.FindObjectOfType<TankScript>();
if (m_Tank == null)
return;
var inspector = new InspectorElement(m_Tank);
rootVisualElement.Add(inspector);
}
}
}
此代码引用 TankScript
脚本并使用 InspectorElement
。
TankScript
脚本是分配给一个游戏对象的 MonoBehaviour 的示例。
Assets/TankScript.cs
的内容:
using UnityEngine;
[ExecuteInEditMode]
public class TankScript : MonoBehaviour
{
public string tankName = "Tank";
public float tankSize = 1;
private void Update()
{
gameObject.name = tankName;
gameObject.transform.localScale = new Vector3(tankSize, tankSize, tankSize);
}
}
InspectorElement 由特定 UI 进行自定义。这是通过 TankEditor
脚本完成的。TankEditor
脚本为 TankScript
类型定义了自定义编辑器。TankEditor
脚本还对层级视图使用 UXML 文件,并使用 USS 文件对 Inspector 进行样式设置。
Assets/Editor/TankEditor.cs
的内容:
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
[CustomEditor(typeof(TankScript))]
public class TankEditor : Editor
{
public override VisualElement CreateInspectorGUI()
{
var visualTree = Resources.Load("tank_inspector_uxml") as VisualTreeAsset;
var uxmlVE = visualTree.CloneTree();
uxmlVE.styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Resources/tank_inspector_styles.uss"));
return uxmlVE;
}
}
Assets/Resources/tank_inspector_uxml.uxml
的内容:
<UXML xmlns:ui="UnityEngine.UIElements" xmlns:ue="UnityEditor.UIElements">
<ui:VisualElement name="row" class="container">
<ui:Label text="Tank Script - Custom Inspector" />
<ue:PropertyField binding-path="tankName" name="tank-name-field" />
<ue:PropertyField binding-path="tankSize" name="tank-size-field" />
</ui:VisualElement>
</UXML>
UXML 文件 tank_inspector_uxml.uxml
用于指定绑定。具体来说,对于每个 PropertyFields
标签,每个 binding-path
属性 (attribute) 都设置为要绑定的属性 (property)。UI 中显示的元素基于每个被绑定属性 (property) 的类型。
Assets/Resources/tank_inspector_styles.uss
的内容:
.container {
background-color: rgb(80, 80, 80);
flex-direction: column;
}
Label {
background-color: rgb(80, 80, 80);
}
TextField:hover {
background-color: rgb(255, 255, 0);
}
FloatField {
background-color: rgb(0, 0, 255);
}
USS 文件 tank_inspector_styles.uss
用于定义每个元素的样式。
下表列出了 PropertyField 支持的字段。每个字段都包含其数据类型。
字段 | Type |
---|---|
BoundsField | Bounds |
BoundsIntField | BoundsInt |
ColorField | Color |
CurveField | AnimationCurve |
FloatField | 浮点精度 |
GradientField | Gradient |
IntegerField | int |
IntegerField | int(对于 ArraySize) |
LayerMaskField | unit |
ObjectField | UnityEngine.Object |
PopupField<string> | Enum |
RectField | Rect |
RectIntField | RecInt |
TextField | string |
TextField,且 maxLength=1 | char |
Toggle | bool |
Vector2Field | Vector2 |
Vector2IntField | Vector2Int |
Vector3Field | Vector3 |
Vector3IntField | Vector3Int |
Vector4Field | Vector4 |
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.