Unity 6 introduces improvements that simplify the creation of custom controls. This guide explains how to migrate custom controls from previous versions to Unity 6’s revamped workflow.
Previously, creating a custom control required using the UxmlTraits
class to define attributes. The following example demonstrates this approach for a ProgressBar
control.
The examples focus on attribute authoring and don’t include the behavior of the control. It creates a UxmlTraits
class that defines the attributes of the ProgressBar
control. For each attribute, the class specifies the following:
Then, it gets the value for each attribute and assigns it to the element. It also adds a UxmlFactory
class that creates instances of the element.
using UnityEngine.UIElements;
public class ProgressBar : VisualElement
{
public new class UxmlFactory : UxmlFactory<ProgressBar, UxmlTraits> { }
public new class UxmlTraits : BindableElement.UxmlTraits
{
UxmlFloatAttributeDescription m_LowValue = new UxmlFloatAttributeDescription { name = "low-value", defaultValue = 0 };
UxmlFloatAttributeDescription m_HighValue = new UxmlFloatAttributeDescription { name = "high-value", defaultValue = 100 };
UxmlFloatAttributeDescription m_Value = new UxmlFloatAttributeDescription { name = "value", defaultValue = 0 };
UxmlStringAttributeDescription m_Title = new UxmlStringAttributeDescription() { name = "title", defaultValue = string.Empty };
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
var bar = ve as ProgressBar;
bar.lowValue = m_LowValue.GetValueFromBag(bag, cc);
bar.highValue = m_HighValue.GetValueFromBag(bag, cc);
bar.value = m_Value.GetValueFromBag(bag, cc);
bar.title = m_Title.GetValueFromBag(bag, cc);
}
}
public string title { get; set; }
public float lowValue { get; set; }
public float highValue { get; set; }
public float value { get; set; }
}
Unity 6 simplifies custom control creation with the UxmlElement
and UxmlAttribute
attributes, eliminating the need for UxmlTraits
and UxmlFactory
. The new system streamlines the process by automatically handling the conversion of values to and from UXML attribute strings.
The following shows the updated the ProgressBar
example:
using UnityEngine.UIElements;
[UxmlElement]
public partial class ProgressBar : VisualElement
{
[UxmlAttribute]
public string title { get; set; }
[UxmlAttribute]
public float lowValue { get; set; }
[UxmlAttribute]
public float highValue { get; set; } = 100;
[UxmlAttribute]
public float value { get; set; }
}
Here’s the key changes:
UxmlElement
to declare a custom control.UxmlAttribute
to define attributes, removing the need for UxmlTraits
.The UXML usage remains the same for both systems:
<ui:UXML xmlns:ui="UnityEngine.UIElements">
<ProgressBar title="My Progress bar" low-value="0" high-value="1" value="0.5" />
</ui:UXML>
If an element lacks the UxmlElement
attribute, Unity defaults to the UxmlTraits
and UxmlFactory
systems for serialization. Ensure consistency by using a single serialization approach per visual elementA node of a visual tree that instantiates or derives from the C# VisualElement
class. You can style the look, define the behaviour, and display it on screen as part of the UI. More info
See in Glossary. While both systems can coexist in a UXML file, don’t mix them with a single element.
After migrating to the new system, reimport UXML assets to match the updated code. While this process happens automatically, but any previously built Asset Bundles containing UXML files need to be rebuilt to function correctly.
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.