UxmlFactory and UxmlTraits are removed in Unity 6.6: use UxmlElement
Unity 6.6 removed the legacy UxmlFactory and UxmlTraits workflow for custom UI Toolkit controls. Convert to the [UxmlElement] and [UxmlAttribute] attributes from Unity 6.0.
- Status
- Removed or stopped working in Unity 6.6 · UI Toolkit
- Old
UxmlFactory<T>, UxmlTraits- New
[UxmlElement], [UxmlAttribute]- Checked
- 2026-10-05, against the sources below
What changed
Custom controls used to expose themselves to UXML through a nested UxmlFactory class and a UxmlTraits class that declared every attribute. Unity 6.0 introduced a simpler attribute-based system, and Unity 6.6 removed the old one, so the old classes no longer compile.
Mark the control partial and add [UxmlElement], then put [UxmlAttribute] on each property UXML should set. The source generator writes the factory for you.
Before and after
public class HealthBar : VisualElement
{
public new class UxmlFactory : UxmlFactory<HealthBar, UxmlTraits> { }
public new class UxmlTraits : VisualElement.UxmlTraits
{
UxmlFloatAttributeDescription max = new() { name = "max", defaultValue = 100 };
// ...
}
}[UxmlElement]
public partial class HealthBar : VisualElement
{
[UxmlAttribute] public float max { get; set; } = 100;
}Find every place it appears
This change needs a hand edit, but the Unity 6 Script Upgrade Checker points to every line it affects, together with the other changes for your target version.
Open this example in the checkerQuestions
- Why does the control have to be partial?
- A source generator writes the factory and attribute code into a second part of your class at compile time. Without partial, the generated part cannot join your class and the build fails.
- Can a UXML attribute have a different name from the property?
- Yes. Pass the name to the attribute:
[UxmlAttribute("max-value")]on a property called MaxValue. Without a name, Unity derives one from the property name.