You can use the SerializedObject data binding system to bind to serialized properties. This means you can bind visual elementsA node of a visual tree that instantiates or derives from the C# VisualElement
class. You can style the look, define the behaviour, and display it on screen as part of the UI. More info
See in Glossary to the following objects that are compatible with the Serialization system:
ScriptableObject
classesMonoBehaviour
classesint
, bool
, or float
.Vector3
, Color
, or Object
.You can only bind the value
property of visual elements that implement the INotifyValueChanged
interface. For example, you can bind TextField.value
to a string
, but you can’t bind TextField.name
to a string
.
You can bind between an object and any visual element that either derives from BindableElement
or implements the IBindable
interface.
To create a binding, either call Bind()
or BindProperty()
.
Bind()
You can call Bind()
to bind an element to a SerializedObject. Before you bind an element, you must set the binding path and create a SerializedObject.
Use this method if you don’t have easy access to the SerializedProperty
for the binding. Refer to Create a binding with a C# script for an example.
The Bind()
extension method sets up an entire hierarchy of visual elements with specified bindingPath
properties. You can call the Bind()
method on a single element or the parent of the hierarchy that you want to bind. For example, you can call Bind()
on the rootVisualElement
of an Editor window. This binds all child elements with specified bindingPath
properties.
Don’t call Bind()
from the Editor.CreateInspectorGUI()
or PropertyDrawer.CreatePropertyGUI()
override. These overrides are called automatically on the visual elements that these methods return.
Unbind()
The Unbind()
method stops the value tracking for the element and all its direct and indirect child elements. In general, you don’t need to call Unbind()
because tracking stops when a user closes the Inspector or Editor window. Call Unbind()
if you must bind elements to different targets in their lifetimes.
If you construct an InspectorElement
in C# by calling its constructor, binding occurs during the constructor call. If you want to rebind an InspectorElement
after it has been constructed, you must call Unbind()
and then either call Bind()
explicitly or let a bind operation from a parent create a binding.
If you call Bind()
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.
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 m_Count
, set the binding path to m_Count
.
If you want to bind a visual element 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’s name property, which is m_Name
, set the binding path to m_Name
.
You can set the binding path in UI(User Interface) Allows a user to interact with your application. Unity currently supports three UI systems. More info
See in Glossary Builder, UXML, or with a C# script:
binding-path
attribute for a visual element. Refer to Define the binding path in UXML for an example.bindingPath
from the IBindable
interface. Refer to Bind with the binding path for an example.BindProperty()
You can call BindProperty()
to bind an element to a SerializedProperty
directly.
Use this method if you already have a SerializedProperty
object, and especially if you traverse the properties of a SerializedObject
to build a UI dynamically. Refer to Bind without the binding path for an example.
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
TemplateContainer
(corresponds to the <Instance>
tag in UXML)GroupBox
Refer to Bind to nested properties for an example.
You can create a binding to receive a callback when a bound serialized property changes. To do so, leverage the TrackPropertyValue()
extension method, which is available to any VisualElement
. This registers a callback that executes when the provided SerializedProperty
changes. Refer to Receive callbacks when a serialized property changes for an example.
You can also create a binding to receive a callback when any properties of the bound serialized object change. To do so, leverage the TrackSerializedObjectValue()
extension method, which is available to any VisualElement
. This registers a callback that executes when the provided SerializedProperty
changes. Refer to Receive callbacks when any properties change for an example.
You can create custom elements and bind them to serialized properties through the value binding system.
To create bindable custom elements:
BindableElement
or implement the IBinding
interface.INotifyValueChanged
interface.SetValueWithoutNotify()
method to the INotifyValueChanged
interface.value
property accessors to the INotifyValueChanged
interface.Refer to Create and style a custom control for an example.
Note: You can’t bind custom data types directly to custom elements because the binding system only allows you to bind an element to a type supported by SerializedPropertyType of enum
. This means you can’t define a class or structure, for example, a struct called MyStruct
, and bind it to an element that implements INotifyValueChanged<MyStruct>
. However, you can bind to serializable nested properties of custom data types. This includes polymorphic serialization (when a field uses the [SerializeReference]
attribute). Refer to Bind a custom control to custom data type for an example.
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 InspectorElement constructed in C# |
During the constructor call |
A child element that is under the return value of CreateInspectorGUI() or CreatePropertyGUI() when those methods return |
After CreateInspectorGUI() or CreatePropertyGUI() returns |
A child element that is under an element when Bind() or BindProperty() is called on the parent element |
During the Bind() or BindProperty() call |
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:
Editor
or custom PropertyDrawer
, set the elements’ binding paths instead of calling Bind()
or BindProperty()
on any visual elements that are in the visual treeAn object graph, made of lightweight nodes, that holds all the elements in a window or panel. It defines every UI you build with the UI Toolkit.CreateInspectorGUI()
or CreatePropertyGUI()
. These elements are bound automatically after CreateInspectorGUI()
or CreatePropertyGUI()
returns. However, if you add any elements to the visual tree after that point, call Bind()
or BindProperty()
to bind them.Bind()
or BindProperty()
regardless of the time at which the elements get added to the visual tree. If you call Bind()
or BindProperty()
and bind multiple controls at the same time, set the binding path of each control and then call Bind()
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 the Bind()
method more than once.When you use an auto-property, the compiler automatically generates a backing field with a name as <PropertyName>k_BackingField
. This field is not explicitly visible in your code but can be referenced if necessary, as in binding scenarios.
For example, the following example defines an auto-property SomeProp
and serializes it:
[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 <SomeProp>k_BackingField
in UXML, you must escape <
and >
because they’re reserved for tags. For example, set the binding-path
as follows:
<editor:PropertyField name="some-prop" binding-path="<SomeProp>k_BackingField"/>
Try the following examples to learn how to code with data binding:
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.
When you visit any website, it may store or retrieve information on your browser, mostly in the form of cookies. This information might be about you, your preferences or your device and is mostly used to make the site work as you expect it to. The information does not usually directly identify you, but it can give you a more personalized web experience. Because we respect your right to privacy, you can choose not to allow some types of cookies. Click on the different category headings to find out more and change our default settings. However, blocking some types of cookies may impact your experience of the site and the services we are able to offer.
More information
These cookies enable the website to provide enhanced functionality and personalisation. They may be set by us or by third party providers whose services we have added to our pages. If you do not allow these cookies then some or all of these services may not function properly.
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us to know which pages are the most and least popular and see how visitors move around the site. All information these cookies collect is aggregated and therefore anonymous. If you do not allow these cookies we will not know when you have visited our site, and will not be able to monitor its performance.
These cookies may be set through our site by our advertising partners. They may be used by those companies to build a profile of your interests and show you relevant adverts on other sites. They do not store directly personal information, but are based on uniquely identifying your browser and internet device. If you do not allow these cookies, you will experience less targeted advertising. Some 3rd party video providers do not allow video views without targeting cookies. If you are experiencing difficulty viewing a video, you will need to set your cookie preferences for targeting to yes if you wish to view videos from these providers. Unity does not control this.
These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms. You can set your browser to block or alert you about these cookies, but some parts of the site will not then work. These cookies do not store any personally identifiable information.