How to create custom UXML elements? (No registered factory method error)

I’m attempting to make a custom element (or a 'control ’ as it seems to be called in some docs?) but I’m getting this runtime error:

Element 'test.CountdownTimerElement' is missing a UxmlElementAttribute and has no registered factory method. Please ensure that you have the correct namespace imported.
UnityEngine.UIElements.UIDocument:OnEnable ()

I’m basing my implemetation on this which appears to be outdated.

This is my custom element class:

using UnityEngine;
using UnityEngine.UIElements;

[UxmlElement]
public partial class CountdownTimerElement : VisualElement
{
    public new class UxmlFactory : UxmlFactory<CountdownTimerElement> { }
    
    private Label _timerLabel;

    public CountdownTimerElement()
    {
        _timerLabel = new Label();
        Add(_timerLabel);
        _timerLabel.style.fontSize = 24;
    }

    public void UpdateCountdown(int timeLeft)
    {
        _timerLabel.text = timeLeft > 0 ? timeLeft.ToString() : "Go!";
    }

    public void HideCountdown()
    {
        _timerLabel.text = string.Empty;
    }
}

This is my template where the element is referenced:

<UXML 
    xmlns="UnityEngine.UIElements" 
    xmlns:test="test"
    xsi="http://www.w3.org/2001/XMLSchema-instance" 
    engine="UnityEngine.UIElements" 
    noNamespaceSchemaLocation="../../../../../../UIElementsSchema/UIElements.xsd" 
    editor-extension-mode="False">

    <VisualElement name="time-count-container" class="time-count-container">
        <test:CountdownTimerElement name="countdownTimerElement" />
    </VisualElement>

</UXML>

I’m not sure which specific UxmlElementAttribute that I’m missing, as far as I’m aware there isn’t a requirement for an attribute, if there is I’m guessing it’s the “name” attribute which is used to select the element in scripts.

Any advice on what I’m doing wrong would be appreciated :smiley:

You don’t need the UxmlFactory, that’s the old system that UxmlElement replaced.
It looks like you have an incorrect namespace.

CountdownTimerElement does not appear to be in a namespace but the uxml is putting it in the ‘test’ namespace. Remove the test: part in the uxml so it’s <CountdownTimerElement instead.

2 Likes

Additionally, all the docs related to UI Toolkit are now in the Unity manual, for example:

The docs from com.unity.ui or com.unity.ui.builder are outdated

2 Likes

Thank you for the links to the correct docs guys :smiley:

Sadly I’m still getting an error after updating my code to create a simple control.

It’s the same similar to the previous error I was getting (this time triggered in OnValidate rather than OnEnable):

Element 'UnityEngine.UIElements.CountdownTimerElement' is missing a UxmlElementAttribute and has no registered factory method. Please ensure that you have the correct namespace imported.
UnityEngine.UIElements.UIDocument:OnValidate ()

Updated class:

using UnityEngine.UIElements;

[UxmlElement]
public partial class CountdownTimerElement : VisualElement {
    
    [UxmlAttribute]
    public string myString { get; set; } = "default_value";

    [UxmlAttribute]
    public int myInt { get; set; } = 2;
}

Used in my UXML template like this:

<UXML 
    xmlns="UnityEngine.UIElements"
    xsi="http://www.w3.org/2001/XMLSchema-instance" 
    engine="UnityEngine.UIElements" 
    editor="UnityEditor.UIElements"
    noNamespaceSchemaLocation="../../../../../../UIElementsSchema/UIElements.xsd" 
    editor-extension-mode="False">

    <VisualElement name="countdown-container" class="countdown-container">
        <CountdownTimerElement name="countdownTimerElement" myInt="6" />
    </VisualElement>
</UXML>

I’ve removed the “test” namespace, I only added that to test if that would prevent the error as it mentioned needing a “correct namespace”.

I’ve used the UI Debugger tool to see check out the hierarchy too:
image

Looks like the CountdownTimerElement is not in the hierarchy or it’s recognised as a Label?

I’m sure I’ve made a small mistake somewhere if anyone would be kind enough to point it out?

Thanks again!

EDIT: Just to cover all bases, I’ve also copied the exact ExampleVisualElement class from the link @karl_jones posted and I’m still getting the same error.

This element however does show up in the UI with the default text:

Unknown Type: UnityEngine.UIElements.ExampleElement

Here it is in the hierarchy (Also rendering as a Label):
image

I’ve also tried to use the UI Builder (which I do not use for UI Toolkit dev currently) and could see that the custom controls are listed. When I add the custon controls manually via the builder there’s no difference to the outcome; the same error occurs and the hierarchy shown in the UI Debugger tool still shows the controls have been detected as Labels.

image

The clue is in the error

UnityEngine.UIElements.CountdownTimerElement

It thinks that CountdownTimerElement is in the namespace UnityEngine.UIElements. This is the reason why:

xmlns=“UnityEngine.UIElements”

You are setting a default namespace, if a namespace is not specified then it uses this. You should remove that.

Then update any references to use the prefix you have already specified, engine.

<engine:VisualElement

Etc

1 Like