Explaining Access To Unity's UxmlAssetAttributeDescription of UI Toolkit for version 2022.3F LTS

Hello everyone, this isnt your typical showcase about a full module or tool but instead i found a lack of explanation about how to use

public class UxmlAssetAttributeDescription<T>

For versions prior 2023.1f+ so i dedided to provide my findings after using it.

Its important to add a word of warning regarding uses based on unity staff replies : New feature : Drag and drop assets on your custom controls - #17 by antoine-unity

The reason it wasn’t made public in this version is that, in the event that your code definition for the custom element changes (for example, add or remove an UxmlAssetAttributeDescription to the traits), affected UXML files do not get re-imported. So you may have an out of date import result until the next import of the UXML.
It might not be an issue for some users but it wouldn’t be solid enough for general availability.

If you kept reading its a 2 step process (with similar approaches based on what you may need).

  1. Create a folder with an assembly reference to Unity.UI Assembly. Then we create a new traits class extending the traits class of VisualElement.UxmlTraits. If you need this base to have more fields you can just add more asset attributes and then use more Generic definitions to pass the types. (<T1, T2…, Tx>)
namespace UnityEngine.UIElements
{
    public class PublicUxmlAssetAttributeDescriptionTrait<T> : VisualElement.UxmlTraits where T : Object
    {
        protected PublicUxmlAssetAttributeDescriptionTrait(string Name = "AssetUxmlValue")
        {
            uxmlAssetAttributeDescription = new UxmlAssetAttributeDescription<T>() { name = Name};
        }

        internal UxmlAssetAttributeDescription<T> uxmlAssetAttributeDescription;
            
        public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
        {
            base.Init(ve, bag, cc);

            UxmlAssetAttributeDescriptionValue = uxmlAssetAttributeDescription.GetValueFromBag(bag, cc);
        }
        
        public T UxmlAssetAttributeDescriptionValue { get; set; }
    }
}
  1. Simply in your Custom Control / Custom Visual Element inherrit from this class when adding your UxmlTrait definition and ensure you add a constructor with the name of your property where the attribute is going to link.
public class MyCustomVE : VisualElement
{
        public new class UxmlFactory : UxmlFactory<MyCustomVE, UxmlAssetAttributeDescriptionTraits>{}

        public new class UxmlAssetAttributeDescriptionTraits : PublicUxmlAssetAttributeDescriptionTrait<MyScriptableObjectExample>
        {
            //Here we pass the name to the base so its necessary!
            public UxmlAssetAttributeDescriptionTraits() : base("myPropertyName"){}
            
            public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
            {
                base.Init(ve, bag, cc);
                var ate = ve as MyCustomVE ;

                ate.myPropertyName = UxmlAssetAttributeDescriptionValue;
            }
        }

        //Example of the property we pass
        private MyScriptableObjectExample myPropertyName { get; set; } 
        //Example of a simple SO definition
        private class MyScriptableObjectExample : ScriptableObject {}
}
1 Like