Version: 2022.1
Structuring UXML attributes
Styling UI

Create custom elements

Custom elements are a way to embed complex UI-related functionality directly in the UI code. For example, take the IntegerField control. This is a single custom 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.

To create a new custom element in C#, inherit it from the VisualElement class. This allows 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 can 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. You can categorize custom controls by creating your class is in a namespace.

You can add additional custom UXML attributes like this:

using UnityEngine;
using UnityEngine.UIElements;

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; }
}

You must expose your element class to a { get; set; } C# property that has the same name as the name you set in your Uxml*AttributeDescription with the camelCasing format. For example, if your UXML attribute’s name is my-int, the C# property name must be myInt.

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

CustomElementAttributes
CustomElementAttributes

The UXML looks like this:

 <MyElement string-attr="my-string" int-attr="5" />

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

Structuring UXML attributes
Styling UI