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:
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.