Search Unity

Question How to display editor-only serialized class with property drawer? (UI Toolkit)

Discussion in 'Scripting' started by CharacterControllerRespecter, Feb 28, 2024.

  1. CharacterControllerRespecter

    CharacterControllerRespecter

    Joined:
    Apr 7, 2017
    Posts:
    60
    I am building a fairly large custom inspector that I am trying to separate into several pieces. In addition to the main custom editor class, I have several serializeable classes that contain settings data that affect the behavior of the custom inspector; for example, if certain bools are toggled, one set of settings might be displayed. These data classes, and some other general serialized data, are being stored in a ScriptableSingleton from which the custom editor reads. The whole setup looks something like this:

    Code (CSharp):
    1. public class SomeMonoBehaviour : MonoBehaviour { }
    2.  
    3. [CustomEditor(typeof(SomeMonoBehaviour))]
    4. public class SomeMonoBehaviourEditor : Editor { }
    5.  
    6. [Serializeable]
    7. public class DebugSettingsA // Editor only; has nothing to do with any MonoBehaviours
    8. {
    9.     [SerializeField] private Color _someColor;
    10.     // Many more fields...
    11. }
    12.  
    13. [CustomPropertyDrawer(typeof(DebugSettingsA))]
    14. public class DebugSettingsADrawer : PropertyDrawer
    15. {
    16.     [SerializeField] private VisualTreeAsset _UXML; // The UXML for this property drawer only
    17.  
    18.     private ColorField _someColorField;
    19.  
    20.     public override VisualElement CreatePropertyGUI(SerializedProperty property)
    21.     {
    22.         // Link everything together from UXML
    23.         _someColorField.BindProperty(property.FindPropertyRelative("_someColor");
    24.     }
    25. }
    26.  
    27. // For brevity, pretend I have the same setup for class DebugSettingsB
    28.  
    29. public class SomeMonoBehaviourEditorSingleton : ScriptableSingleton<SomeMonoBehaviourEditorSingleton>
    30. {
    31.     [SerializeField] private VisualTreeAsset _mainUXML;
    32.     [SerializeField] private StyleSheet _mainUSS;
    33.  
    34.     [SerializeField] private bool _toggleSomeDebugSetup;
    35.     [SerializeField] private _debugSettingsA;
    36.     [SerializeField] private _debugSettingsB;
    37. }
    I want to know if there is a way for me to render the settings' property drawers with this setup, or if I need to build each UXML file (the main UXML and the UXML for every other component, like the settings) in the custom editor file. The reason I am somewhat confused is because Unity typically automatically renders property drawers when their associated types are serialized. Obviously, custom editors work differently, and I know I could still separate everything out with normal classes instead of property drawers. But does something like this exist?

    Code (CSharp):
    1. public class SomeMonoBehaviourEditor : Editor
    2. {
    3.     public override VisualElement CreateInspectorGUI()
    4.     {
    5.         var root = _mainUXML.Instantiate();
    6.         var propertyDrawerElement = new PropertyDrawerField(_debugSettingsA);
    7.         root.Add(propertyDrawerElement);
    8.     }
    9. }
    10.  
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,797
  3. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,808
    Since you say that and your example is code that creates UI Element, I want to stress that you should seriously consider using UI Builder for creating a "fairly large" (or anything but simple, really) UI Interface. It'll make your live and maintenance of that tool a lot easier.

    Especially considering that to try out every code change you have to wait for script compilation / domain reload. You'll be designing the GUI ten times faster with UI Builder simply due to getting instant feedback to every change, particularly when it comes to layout and styling your GUI.
     
  4. CharacterControllerRespecter

    CharacterControllerRespecter

    Joined:
    Apr 7, 2017
    Posts:
    60
    I appreciate your suggestions, and perhaps I will give it a try. I opted to set up everything in code for now because it is very similar to web development with which I am very familiar.
     
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,797
    Personally with the way templates work (and don't work), and the pointless and annoying TemplateContainer that just gets in the way of everything lead me to prefer to code gen 95% of my UI Toolkit visual elements.

    I'll make plenty of custom controls to consolidate code, usually decorated with
    [UxmlAttribute]
    , though most of the time I'm just generating visual elements via code.
     
  6. CharacterControllerRespecter

    CharacterControllerRespecter

    Joined:
    Apr 7, 2017
    Posts:
    60
    I assume you mean generating it with C# code, similar to the previous IMGUI system.
     
  7. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,797
    Yes that's what I meant by 'code gen'.