Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug Element has no registered factory method.??

Discussion in 'UI Toolkit' started by reigota, Oct 2, 2020.

  1. reigota

    reigota

    Joined:
    Mar 23, 2010
    Posts:
    86
    Hi folks!

    Context:
    Unity 2019.4.9f1
    UI Builder: 1.0.0-preview7


    I am creating a fancy tool using uielements and to keep my project organized I decided to create some custom components. I ready the documentation and a few examples and I had a good start.
    Basically, I created 6 components. One of them is very "basic" and is used but others.. and these are used by another. So, I have custom controls that consume other custom controls. So far, so good. Everything working fine.

    BOOM

    Out of the blue I started to have one of my components getting changed (by the builder) for a label with the text: "Unknow type: UIRichLabel". This is (just a coincidence) my most basic custom control. It is a label with an icon. This is the UXML of it:

    Code (XML):
    1. <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
    2.     <ui:VisualElement name="UIRichLabel" style="flex-direction: row; align-items: center;">
    3.         <Style src="FtueEditorWindow3.uss" />
    4.         <ui:VisualElement name="icon" class="hide" style="margin-left: 5px; margin-right: 5px; justify-content: center;" />
    5.         <ui:Label text="LABEL" name="label" style="font-size: 12px;" />
    6.     </ui:VisualElement>
    7. </ui:UXML>
    And this is its related c# code

    Code (CSharp):
    1.  
    2. using System;
    3. using System.Collections.Generic;
    4. using UnityEditor;
    5. using UnityEngine;
    6. using UnityEngine.UIElements;
    7.  
    8. public class UIRichLabel : VisualElement
    9. {
    10.     private const string TEMPLATE_PATH = "Assets/Editor/FTUE/UIRichLabelTemplate.uxml";
    11.  
    12.     private const string ERROR_ICON_STYLE = "error_icon";
    13.     private const string WARNING_ICON_STYLE = "warning_icon";
    14.     private const string INFO_ICON_STYLE = "info_icon";
    15.     private const string NONE_ICON_STYLE = "hide";
    16.  
    17.     public enum IconStyle
    18.     {
    19.         None,
    20.         Error,
    21.         Warning,
    22.         Info
    23.     }
    24.  
    25.     public static readonly Dictionary<IconStyle, string> IconStyles = new Dictionary<IconStyle, string>()
    26.     {
    27.         {IconStyle.None, NONE_ICON_STYLE},
    28.         {IconStyle.Error, ERROR_ICON_STYLE},
    29.         {IconStyle.Warning, WARNING_ICON_STYLE},
    30.         {IconStyle.Info, INFO_ICON_STYLE},
    31.     };
    32.  
    33.     private const string ICON_SELECTOR = "icon";
    34.     private const string LABEL_SELECTOR = "label";
    35.  
    36.     private VisualElement m_icon = default;
    37.     private Label m_label = default;
    38.     private IconStyle m_iconStyle;
    39.     private Color m_color = default;
    40.  
    41.     public string Label
    42.     {
    43.         get { return m_label.text; }
    44.         set { m_label.text = value; }
    45.     }
    46.  
    47.     public int TextSize
    48.     {
    49.         get { return (int)m_label.style.fontSize.value.value; }
    50.         set
    51.         {
    52.             m_label.style.fontSize = new StyleLength(value);
    53.             m_icon.style.height = new StyleLength(value);
    54.             m_icon.style.width = new StyleLength(value);
    55.         }
    56.     }
    57.  
    58.     public Color TextColor
    59.     {
    60.         get { return m_color; }
    61.         set
    62.         {
    63.             m_color = value;
    64.             m_label.style.color = m_color;
    65.         }
    66.     }
    67.  
    68.     public IconStyle Icon
    69.     {
    70.         get { return m_iconStyle; }
    71.         set
    72.         {
    73.             m_iconStyle = value;
    74.             SetStyle(m_iconStyle);
    75.         }
    76.     }
    77.  
    78.     public UIRichLabel()
    79.     {
    80.         VisualTreeAsset template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(TEMPLATE_PATH);
    81.         template.CloneTree(this);
    82.         LoadInternalReferences();
    83.     }
    84.  
    85.     public void LoadInternalReferences()
    86.     {
    87.         m_icon = this.Q<VisualElement>(ICON_SELECTOR);
    88.         m_label = this.Q<Label>(LABEL_SELECTOR);
    89.     }
    90.  
    91.     public void SetLabel(string title, IconStyle style)
    92.     {
    93.         SetLabel(title);
    94.         SetStyle(style);
    95.     }
    96.  
    97.     public void SetLabel(string label)
    98.     {
    99.         m_label.text = label;
    100.     }
    101.  
    102.     public void SetStyle(IconStyle style)
    103.     {
    104.         m_icon.ClearClassList();
    105.         m_icon.AddToClassList(IconStyles[style]);
    106.     }
    107.  
    108.     public void SetClickCallback(Action callback)
    109.     {
    110.         m_label.AddManipulator(new Clickable(callback));
    111.     }
    112.  
    113.     #region UXML stuff
    114.  
    115.     public new class UxmlFactory : UxmlFactory<UIRichLabel, UxmlTraits> { }
    116.  
    117.     public new class UxmlTraits : VisualElement.UxmlTraits
    118.     {
    119.         UxmlEnumAttributeDescription<IconStyle> m_icon = new UxmlEnumAttributeDescription<IconStyle> { name = "icon-style", defaultValue = IconStyle.None };
    120.         UxmlStringAttributeDescription m_label = new UxmlStringAttributeDescription { name = "label", defaultValue = "Label" };
    121.         UxmlIntAttributeDescription m_textSize = new UxmlIntAttributeDescription { name = "text-size", defaultValue = 12 };
    122.         UxmlColorAttributeDescription m_textColor = new UxmlColorAttributeDescription { name = "text-color", defaultValue = Color.black };
    123.  
    124.         public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
    125.         {
    126.             base.Init(ve, bag, cc);
    127.  
    128.             UIRichLabel uIRichLabel = ve as UIRichLabel;
    129.             uIRichLabel.Label = m_label.GetValueFromBag(bag, cc);
    130.             uIRichLabel.Icon = m_icon.GetValueFromBag(bag, cc);
    131.             uIRichLabel.TextSize = m_textSize.GetValueFromBag(bag, cc);
    132.             uIRichLabel.TextColor = m_textColor.GetValueFromBag(bag, cc);
    133.         }
    134.     }
    135.  
    136.     #endregion
    137. }

    When I pass the mouse over another component (in the builder) that uses this richlabel, I got this in the console:

    Code (text):
    1. Element ''UIRichLabel'' has no registered factory method.
    2. UnityEngine.UIElements.VisualTreeAsset:CloneTree()
    3. Unity.UI.Builder.<>c__DisplayClass8_0:<ImportUxmlFromProject>b__0() (at Library/PackageCache/com.unity.ui.builder@1.0.0-preview.7/Editor/Builder/Library/BuilderLibraryProjectScanner.cs:248)
    4. Unity.UI.Builder.BuilderLibraryView:OnItemMouseEnter(MouseEnterEvent) (at Library/PackageCache/com.unity.ui.builder@1.0.0-preview.7/Editor/Builder/Library/BuilderLibraryView.cs:93)
    5. UnityEngine.GUIUtility:processEvent(Int32, IntPtr)

    I read several posts about the possible causes, I saw it used to be related to
    moment when the the uxmlfactory got registred, I saw a few hacks to work it around.. but all old stuff, version 0.0.4 or something like that and supposely already fixed.

    After 3 days trying to fix that..

    BOOOOOM

    Another components start to present the same symptom!! Seems like a cancer spreading out across my components!!

    Please, I need to advices here... anyone with a word to comfort me is also welcome.

    Joao
     
  2. sebastiend-unity

    sebastiend-unity

    Unity Technologies

    Joined:
    Nov 9, 2015
    Posts:
    184
    Hi,

    I tried your usecase and it seems to work well on my side. I created 3 files:

    <Project>/Assets/Editor/FTUE/UIRichLabel.cs with code above
    <Project>/Assets/Editor/FTUE/UIRichLabelTemplate.uxml with uxml definition above
    <Project>/Assets/Editor/FTUE/FtueEditorWindow3.uss with the following inside (just for testing purposes, did not have access to your content):

    Code (CSharp):
    1. .error_icon {
    2.     background-color: #FF0000;
    3. }
    4.  
    5. .warning_icon {
    6.     background-color: #FFFF00;
    7. }
    8.  
    9. .info_icon {
    10.     background-color: #5555FF;
    11. }
    12.  
    13. .hide {
    14.     display: none;
    15. }
    16.  
    Opened the UI Builder (1.0.0-preview.7), with a new UI document (aka project's main UXML file), set Library mode to "Project", found the UIRichLabel and double-clicked on the entry to add an instance to my project's UI document, everything worked out fine. I will probably need more contextual info to repro. How are you using the UIRichLabel specifically?

    Sebastien
     
  3. AdamBebko

    AdamBebko

    Joined:
    Apr 8, 2016
    Posts:
    164
    Having exact same problem. Was working fine, then next time I rebooted unity this occurred.

    Seems to struggle when it clones it into my inspector. What's strange is taking it outside of an assembly fixes it. My assembly is referencing UnityEditor.UI, UnityEngine.UI, UnityEngine.UIElementsModule, UnityEditor.UIElementsModule. No bugs in console until I try to open inspector.

    Error:

    Code (CSharp):
    1. Element 'RandomizableFloatField' has no registered factory method.
    2. UnityEngine.UIElements.VisualTreeAsset:CloneTree (UnityEngine.UIElements.VisualElement)
    3. BubblesEditorHelpers.BubblePositionInspector:CreateInspectorGUI () (at Assets/Scripts/BubblesEditorHelpers/BubblePositionInspector.cs:26)
    4. UnityEditor.InspectorWindow:RedrawFromNative () (at /Users/bokken/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:144)
    Code (CSharp):
    1. using Bubbles;
    2. using UnityEditor;
    3. using UnityEditor.UIElements;
    4. using UnityEngine;
    5. using UnityEngine.UIElements;
    6.  
    7. namespace BubblesEditorHelpers {
    8.     [CustomEditor(typeof(BubblePosition))]
    9.     public class BubblePositionInspector : Editor {
    10.  
    11.         [SerializeField] VisualTreeAsset bubbleInspector;
    12.         BubblePosition bubblePositionEditor;
    13.         VisualElement thisInspector;
    14.         Foldout defaultInspector;
    15.  
    16.  
    17.         public override VisualElement CreateInspectorGUI()
    18.         {
    19.             thisInspector = new VisualElement();
    20.  
    21.             if (bubbleInspector == null) {
    22.                 DrawDefaultInspector(thisInspector);
    23.                 return thisInspector;
    24.             }
    25.  
    26.             bubbleInspector.CloneTree(thisInspector); <--- Error
    27.    
    28.  
    29.        

    This is in the same assembly:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEditor.UIElements;
    3. using UnityEngine.UIElements;
    4.  
    5. namespace BubblesEditorHelpers {
    6.     public class RandomizableFloatField : Foldout
    7.     {
    8.  
    9.         public new class UxmlFactory : UxmlFactory<RandomizableFloatField, UxmlTraits> { } <--- factory
    10.        

    Update: It required removing the namespace of the custom VisualElement to fix it, not necessarily the assembly. It works in an assembly as long as there's no namespace in the file.
     
    Last edited: Oct 6, 2021
    craftsmanbeck likes this.
  4. orb_9

    orb_9

    Joined:
    Feb 10, 2010
    Posts:
    47
    Unity 2021.2.8f1 here.

    In my case this happens when I change the namespace of the custom element. The element already was in a namespace and worked fine. After changing the namespace the

    Element 'Foobar' has no registered factory method.
    errors started appearing.
    Changing the namespace back to the original resolved the issue.
     
  5. ProgrammerJens

    ProgrammerJens

    Joined:
    Jun 3, 2013
    Posts:
    12
    Same error here after I renamed the namespace in my .cs file (Unity 2021.2.7f1).

    I could fix it by manually editing the .uxml file in a text editor and renaming the namespace to the new one.

    Before (old namespace "Game.Play")
    Code (XML):
    1. <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
    2.     <ui:Template name="PlayOverlay" src="project://database/Assets/Data/Ui/PlayOverlay.uxml?fileID=9197481963319205126&amp;guid=8f3a6ea49da1aab4881b973bb23dde2c&amp;type=3#PlayOverlay" />
    3.     <Game.Play>
    4.         <ui:Instance template="PlayOverlay" name="PlayOverlay" />
    5.     </Game.Play>
    6. </ui:UXML>
    Fixed (new namespace "Game.Ui.Play") - replaced "Game.Play" with "Game.Ui.Play"
    Code (XML):
    1. <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
    2.     <ui:Template name="PlayOverlay" src="project://database/Assets/Data/Ui/PlayOverlay.uxml?fileID=9197481963319205126&amp;guid=8f3a6ea49da1aab4881b973bb23dde2c&amp;type=3#PlayOverlay" />
    3.     <Game.Ui.Play>
    4.         <ui:Instance template="PlayOverlay" name="PlayOverlay" />
    5.     </Game.Ui.Play>
    6. </ui:UXML>
     
  6. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    771
    We're likely going to support the [MovedFromAttribute] on VisualElement classes so that UXML assets remain compatible with the former namespace.
    Unfortunately this class is not documented but it is public and used a lot at Unity.
    When using the [SerializedReference] attribute in regular Unity serialization, this is also this attribute that is used to avoid breaking existing asset (see this thread).

    It's not perfect but it can be useful to avoid breaking all assets when renaming a namespace.
     
  7. dylanmanningke10

    dylanmanningke10

    Joined:
    Jan 26, 2022
    Posts:
    5
    Did you solve your problem?