docs.unity3d.com
    Show / Hide Table of Contents

    Using custom (C#) elements

    Custom C# elements are a useful way to embed complex UI-related functionality directly in the UI code. For example, take the IntegerField control. This is a single custom C# element that appears and behaves like a single atomic element in both UXML and in UI Builder, but internally it creates a complex hierarchy of elements and manages user input, data validation, bindings, and a state machine.

    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 will not automatically expose it in UXML and UI Builder. To expose your new element type in UXML and UI Builder, you need the UxmlFactory defined, 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 is 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 Inspector pane.

    Here's what the above custom attributes look like in the Inspector pane:
    CustomElementAttributes

    UI Builder currently does not support fully custom Inspectors for custom C# elements.

    Back to top
    Copyright © 2023 Unity Technologies — Terms of use
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX on 18 October 2023