The purpose of bindings is to synchronize properties within objects to the visible UI(User Interface) Allows a user to interact with your application. More info
See in Glossary.
A binding refers to the link between the property and the visual control that modifies it.
Binding is done between an object and any UIElement that either derives from BindableElement or implements the IBindable interface.
From the UnityEditor.UIElements
namespace:
Base Class:
Controls:
From the UnityEngine.UIElements
namespace:
Base Class
Controls
Binding is done by following these steps while using a Control from one of the namespaces listed above.
The following code snippet shows how to create a binding with C# code. To use this snippet, save this example as a C# file in an editor folder, in your project. Name the C# file SimpleBindingExample.cs
.
The contents of 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)
{
// Create serialization object
SerializedObject so = new SerializedObject(selectedObject);
// Bind it to the root of the hierarchy. It will find the right object to bind to...
rootVisualElement.Bind(so);
// ... or alternatively you can also bind it to the TextField itself.
// m_ObjectNameBinding.Bind(so);
}
else
{
// Unbind the object from the actual visual element
rootVisualElement.Unbind();
// m_ObjectNameBinding.Unbind();
// Clear the TextField after the binding is removed
m_ObjectNameBinding.value = "";
}
}
}
}
In Unity, select Window > UIElementsExamples > Simple Binding Example. You can use this window to select any GameObject in your scene and modify its name with the TextField shown.
This section shows how to use binding through the UXML hierarchy set-up.
In UXML, the attribute binding-path
is defined in the TextField controlA TextField control displays a non-interactive piece of text to the user, such as a caption, label for other GUI controls, or instruction. More info
See in Glossary. This is what binds the control to the effective property of the object.
The contents of 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>
The contents of 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)
{
// Create serialization object
SerializedObject so = new SerializedObject(selectedObject);
// Bind it to the root of the hierarchy. It will find the right object to bind to...
rootVisualElement.Bind(so);
}
else
{
// Unbind the object from the actual visual element
rootVisualElement.Unbind();
// Clear the TextField after the binding is removed
// (this code is not safe if the Q() returns null)
rootVisualElement.Q<TextField>("GameObjectName").value = "";
}
}
}
}
An InspectorElement
is the UIElement counterpart of an inspectorA Unity window that displays information about the currently selected GameObject, Asset or Project Settings, alowing you to inspect and edit the values. More info
See in Glossary that is meant a specific type of Unity object. Using an InspectorElement
to inspect objects gives the following advantages :
Another simple binding example, found under Assets/Editor/SimpleBindingExample.cs
, provides a usage example and an overview of the process.
The contents of 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);
}
}
}
This code references the TankScript
script and uses the InspectorElement
.
The TankScript
script is an example of a MonoBehaviour assigned to a GameObjectThe fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to it. More info
See in Glossary.
The contents of 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);
}
}
The InspectorElement is customized with a specific UI. This is done with the TankEditor
script. The TankEditor
script defines a custom editor for the TankScript
type. The TankEditor
script also uses a UXML file for the hierarchy and a USS file to style the inspector.
The contents of 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;
}
}
The contents of 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>
The UXML file, tank_inspector_uxml.uxml
specifies the binding. Specifically, each binding-path
attribute, for each the PropertyFields
tag, is set to the property to bind. What element is shown in the UI is based on the type of each bound property.
The contents of 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);
}
The USS file, tank_inspector_styles.uss
, defines the style of each element.
The following table lists the fields supported by the PropertyField. Each field includes its data type.
Field | Type |
---|---|
BoundsField | Bounds |
BoundsIntField | BoundsInt |
ColorField | Color |
CurveField | AnimationCurve |
FloatField | float |
GradientField | Gradient |
IntegerField | int |
IntegerField | int, for the ArraySize |
LayerMaskField | unit |
ObjectField | UnityEngine.Object |
PopupField<string> | Enum |
RectField | Rect |
RectIntField | RecInt |
TextField | string |
TextField, with a maxLength=1 | char |
Toggle | bool |
Vector2Field | Vector2 |
Vector2IntField | Vector2Int |
Vector3Field | Vector3 |
Vector3IntField | Vector3Int |
Vector4Field | Vector4 |