Custom control property is not properly setting linked [UxmlAttribute] variable value

I’m trying to create a UI toolkit custom control with the new [UxmlAttribute] system, using this documentation page as my main reference.

using UnityEngine;
using UnityEngine.UIElements;

[UxmlElement]
public partial class Test : VisualElement
{
    public Test() {
        Debug.Log(foo);
    }

    [UxmlAttribute]
    public string foo {get; set;} = "";
}

It properly creates the string field in UI Builder, and it saves to UXML and everything, but Debug.Log(foo); prints out a blank string, as if the actual value were never changed.


Also, I tried the old way (factory/trait), and it does work, except for the fact that UI Builder does not keep whatever I wrote in the field when I save (in the UXML file the value is preserved though).
Am I missing something? Or is this really a bug?

The values wont be changed in the constructor, thats the first thing that gets called when the element is created, before we can apply the serialized values. The values are applied after the element has been created. You could try using the AttachToPanel event which will be called after all the values have been applied. You can also use the property set method to see when the value is being applied.

1 Like

It finally worked, thanks! Do you think this should be a bit more explicit in the docs? Maybe adding a piece of code in this page that calls the constructor, RegisterCallback and Debug.Log to a variable? For example:

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

[UxmlElement]
public partial class ExampleVisualElement : VisualElement
{
    [UxmlAttribute]
    public string myStringValue { get; set; }

    [UxmlAttribute]
    public int myIntValue { get; set; }

    [UxmlAttribute]
    public float myFloatValue { get; set; }

    [UxmlAttribute]
    public List<int> myListOfInts { get; set; }

    [UxmlAttribute, UxmlTypeReference(typeof(VisualElement))]
    public Type myType { get; set; }

    [UxmlAttribute]
    public Texture2D myTexture { get; set; }

    [UxmlAttribute]
    public Color myColor { get; set; }

    public ExampleVisualElement() {
        RegisterCallback<AttachToPanelEvent>(e => {
            Debug.Log(myStringValue);
        });
    }
}

And a brief text explaining RegisterCallback’s use there?

Glad it’s working. We do already have docs for these areas, I’m not sure about this particular example though. It really depends on what you want to do with the values, typically you would handle the value during the property set value.