Using [SerializedField] on a property in combination with [UxmlAttribute]

I was asking myself if using [SerializedField] on a property in combination with [UxmlAttribute] is officially supported?

TLDR: My conclusion is: yes, it is.

Let’s assume I have a property on a custom element that does NOT have a simple backing field that can be serialized directly (i.e. it’s a property that executes some logic and fetches/stores data elsewhere).

According to the docs the UxmlAttribute does automatically generate a separate serializable field in an object of type UxmlSerializedData.

So in theory a backing field for serialization should be generated within the UxmlSerializedData and it seems this works. Here is a code example:

#if UNITY_6000_0_OR_NEWER
[UxmlAttribute("Blur-Strength")]
[SerializeField] // <- Usually this should not work on properties but thanks to UxmlAttribute it does.
#endif
public float BlurStrength
{
    get
    {
        return BlurManager.Instance.Offset;
    }

    set
    {
        if (value != BlurManager.Instance.Offset)
        {
            // Do some stuff
        }
    }
}

I have found a strong indication that this is how it is supposed to work in the docs:

When a field or property is associated with a UXML attribute, all of its attributes are transferred over to the serialized version. This allows for the support of custom property drawers and decorator attributes, such as HeaderAttribute, TextAreaAttribute, RangeAttribute, TooltipAttribute, and so on.

I wonder why there are no examples for this “property binding” in the docs as this is a really handy addition in Unity 6 (or rather 2023.2 to be precise).

You dont need to do this because we already do it for you. We create a serialized field and transfer the attributes over to it, SerializeField is always added. One thing to be careful of is using SerializeReference, that we dont support although we do use it internally for the UxmlObject system.

Theres more details in a blog post I wrote here GitHub - karljj1/UxmlSerializedDataBlogPost

1 Like

Thanks, interesting. Are those then also picked up by the runtime data binding as binding path targets? Will have to do some testing.

No, the UxmlSerializedData is used before an element is instantiated so theres not much point in binding to that data. The property fields in the element can be bound but require you to add the CreateProperty attribute.

1 Like

Ah okay, thank you.

It seems both [CreateProperty] and [SerializeField] trigger showing the “Add binding” in the UI Builder.

Not sure if adding [SerializeField] should have that effect as it seems redundant or wrong if the binding is then “invalid”.

Ah this is UI Builder magic :wink:
The binding its adding is to the VisualElement field, not the serialized data.

1 Like

Magic indeed. Thanks for replying so quickly. Much appreciated :slight_smile:

1 Like