Introduction to SerializedObject data binding
Get started with SerializedObject data binding.
Read time 7 minutesLast updated 3 days ago
You can use the SerializedObject data binding system to bind to serialized properties. This means you can bind visual elements to the following objects that are compatible with the Serialization system:
- User-defined classes
ScriptableObject - User-defined classes
MonoBehaviour - Native Unity component types
- Native Unity asset types
- Primitive C# types such as ,
int, orbool.float - Native Unity types such as ,
Vector3, orColor.Object
Value binding
You can only bind the property of visual elements that implement the interface. For example, you can bind to a , but you can't bind to a .
valueINotifyValueChangedTextField.valuestringTextField.namestringYou can bind between an object and any visual element that either derives from or implements the interface.
BindableElementIBindableCreate a binding
To create a binding, either call or .
Bind()BindProperty()Call Bind()
Bind()You can call to bind an element to a SerializedObject. Before you bind an element, you must set the binding path and create a SerializedObject.
Bind()Use this method if you don't have easy access to the for the binding. Refer to Create a binding with a C# script for an example.
SerializedPropertyThe extension method sets up an entire hierarchy of visual elements with specified properties. You can call the method on a single element or the parent of the hierarchy that you want to bind. For example, you can call on the of an Editor window. This binds all child elements with specified properties.
Bind()bindingPathBind()Bind()rootVisualElementbindingPathDon't call from the or override. is called automatically on the visual elements that these methods return.
BindEditor.CreateInspectorGUIPropertyDrawer.CreatePropertyGUIBindCall Unbind()
Unbind()The method stops the value tracking for the element and all its direct and indirect child elements. In general, you don't need to call because tracking stops when a user closes the Inspector or Editor window. Call if you must bind elements to different targets in their lifetimes.
Unbind()Unbind()Unbind()If you construct an in C# by calling its constructor, binding occurs during the constructor call. If you want to rebind an after it has been constructed, you must call and then either call explicitly or let a bind operation from a parent create a binding.
InspectorElementInspectorElementUnbind()Bind()Set binding path
If you call to create the binding, you must set the visual element's binding path to the property name of the object that you want to bind to.
Bind()For example:
-
If you have the following component script:using UnityEngine;public class MyComp : MonoBehaviour{ [SerializeField] int m_Count;}To bind your visual element to, set the binding path to
m_Count.m_Count -
If you want to bind a visual element to a GameObject's name property, which is, set the binding path to
m_Name.m_Name
You can set the binding path in UI Builder, UXML, or with a C# script:
- In UI Builder, enter the binding path in the Binding Path field for a visual element in the Inspector.
- In UXML, set the attribute for a visual element. Refer to Define the binding path in UXML for an example.
binding-path - In C#, set from the
bindingPathinterface. Refer to Bind with the binding path for an example.IBindable
Call BindProperty()
BindProperty()You can call to bind an element to a directly.
BindProperty()SerializedPropertyUse this method if you already have a object, and especially if you traverse the properties of a to build a UI dynamically. Refer to Bind without the binding path for an example.
SerializedPropertySerializedObjectBind elements to nested properties
You can bind a visual element to nested properties in the source object. To do so, combine the binding path of an element with the binding path of the first ancestor. Use this method with the following elements:
BindableElement- (corresponds to the
TemplateContainertag in UXML)<Instance> GroupBox
Refer to Bind to nested properties for an example.
Receive callbacks when values change
You can create a binding to receive a callback when a bound serialized property changes. To do so, leverage the extension method, which is available to any . This registers a callback that executes when the provided changes. Refer to Receive callbacks when a serialized property changes for an example.
TrackPropertyValue()VisualElementSerializedPropertyYou can also create a binding to receive a callback when any properties of the bound serialized object change. To do so, leverage the extension method, which is available to any . This registers a callback that executes when the provided changes. Refer to Receive callbacks when any properties change for an example.
TrackSerializedObjectValue()VisualElementSerializedObjectBind custom elements
You can create custom elements and bind them to serialized properties through the value binding system.
To create bindable custom elements:
- Declare a custom element.
- Inherit the element from or implement the
BindableElementinterface.IBindable - Implement the interface.
INotifyValueChanged - Implement the method of the
SetValueWithoutNotify()interface.INotifyValueChanged - Implement the property accessors of the
valueinterface.INotifyValueChanged
Refer to Create and style a custom control for an example.
Bind time
Based on the type of UI you create, binding occurs at various times. This is called bind time.
The following table describes the bind time of a control:
Condition | Automatic bind time (assuming binding path was set) |
|---|---|
An | During the constructor call |
A child element that is under the return value of | After |
A child element that is under an element when | During the |
| Other | No automatic binding; you must bind the element or one of its parents manually |
The following are best practices when creating a binding regarding bind time:
- If you create a custom or custom
Editor, set the elements' binding paths instead of callingPropertyDrawerorBind()on any visual elements that are in the visual tree by the end of the body ofBindProperty()orCreateInspectorGUI(). These elements are bound automatically afterCreatePropertyGUI()orCreateInspectorGUI()returns. However, if you add any elements to the visual tree after that point, callCreatePropertyGUI()orBind()to bind them.BindProperty() - If you create any other type of UI, call or
Bind()regardless of the time at which the elements get added to the visual tree. If you callBindProperty()orBind()and bind multiple controls at the same time, set the binding path of each control and then callBindProperty()on the lowest-level parent element that encompasses all the controls.Bind()binds the element on which it's called if it has a binding path and recursively binds all its child elements if they have binding paths. To prevent a negative performance impact, don't bind a visual element with theBind()method more than once.Bind()
Bind to a serialized property backing field
When you use an auto-property, the compiler automatically generates a backing field with a name as . This field is not explicitly visible in your code but can be referenced if necessary, as in binding scenarios.
<PropertyName>k__BackingFieldFor example, the following example defines an auto-property and serializes it:
SomeProp[field: SerializeField] public float SomeProp { get; private set; }
The compiler generates the following backing field:
[SerializedField]private float <SomeProp>k__BackingField;public float SomeProp{ get => <SomeProp>k__BackingField; set => <SomeProp>k__BackingField = value;}
To bind to in UXML, you must escape and because they're reserved for tags. For example, set the as follows:
<SomeProp>k__BackingField< >binding-path<editor:PropertyField name="some-prop" binding-path="<SomeProp>k__BackingField"/>
Binding examples
Try the following examples to learn how to code with data binding:
- Bind with binding path in C# script
- Bind without the binding path
- Bind with UXML and C#
- Create a binding with the Inspector
- Bind to nested properties
- Bind to a UXML template
- Receive callbacks when a bound property changes
- Receive callbacks when any bound properties change
- Bind to a list with ListView
- Bind to a list without ListView
- Bind a custom control
- Bind a custom control to custom data type