Version: 2021.2
Structuring UXML attributes
Styling UI

Using custom (C#) elements

Custom C# elements are a way to embed complex UI-related functionality directly in the UI(User Interface) Allows a user to interact with your application. Unity currently supports three UI systems. More info
See in Glossary
code. For example, take the IntegerField control. This is a single custom C# element that appears and behaves like a single element in both UXML and in UI Builder, but internally it creates a hierarchy of elements that manages user input, data validation, and data bindings.

You can create a new custom C# element in C# by inheriting from the VisualElement class. This will allow you to create and use this element in C# but won’t automatically expose it in UXML and UI Builder. To expose your new element type in UXML and UI Builder, you need to define the UxmlFactory, like this:

class MyElement : VisualElement
{
    public new class UxmlFactory : UxmlFactory<MyElement, UxmlTraits> { }
}

After you add the UxmlFactory to your class, you will be able to create your element in UXML via the <MyElement> tag and find it in the UI Builder’s Library, under the Project tab, in the Custom Controls (C#) section. Further categorization will be created if your class is in a namespace.

You can expose additional custom UXML attributes like this:

class MyElement : VisualElement
{
    public new class UxmlFactory : UxmlFactory<MyElement, UxmlTraits> { }

    public new class UxmlTraits : VisualElement.UxmlTraits
    {
        UxmlStringAttributeDescription m_String =
            new UxmlStringAttributeDescription { name = "string-attr", defaultValue = "default_value" };
        UxmlIntAttributeDescription m_Int =
            new UxmlIntAttributeDescription { name = "int-attr", defaultValue = 2 };

        public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
        {
            get { yield break; }
        }

        public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
        {
            base.Init(ve, bag, cc);
            var ate = ve as MyElement;

            ate.stringAttr = m_String.GetValueFromBag(bag, cc);
            ate.intAttr = m_Int.GetValueFromBag(bag, cc);
        }
    }

    public string stringAttr { get; set; }
    public int intAttr { get; set; }
}

UI Builder adds one additional requirement on top of what’s already required for pure UXML attributes to work. UI Builder requires your element class to expose a { get; set; } C# property that has the same name as the name you set in your Uxml*AttributeDescription, except instead of dashes, the C# property name needs to be using camelCasing. For example, if your UXML attribute is named my-int, the C# property name should be myInt. This is because the UI Builder relies on these C# properties to read the value of the C# attributes to populate its InspectorA Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
See in Glossary
pane.

Here are the above custom attributes displayed in the Inspector pane:

CustomElementAttributes
CustomElementAttributes

UI Builder currently doesn’t support custom Inspectors for custom C# elements.

Structuring UXML attributes
Styling UI