Search Unity

UI Elements draw default inspector

Discussion in 'UI Toolkit' started by LaneFox, Nov 6, 2019.

  1. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,532
    Is there an easy way to draw the default inspector for a target object inside an EditorWindow or to get it back as a VisualElement?
     
  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
  3. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,532
    Demexis likes this.
  4. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    misabiko and LaneFox like this.
  5. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,532
    This worked great, thanks for pointing me to it. InspectorElement worked too, but having everything in UIElements when possible is better IMO.

    Is there a reason that only some of the Attributes are rendered with this approach? For instance [Range()] will display correctly, but [Header()] and [Space()] will not.
     
    Last edited: Nov 9, 2019
  6. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    UIElements does not yet implement the various property drawing attributes you can add on your fields to display them differently. They will all draw using IMGUI. This is just missing functionality, not a technical limitation. You can actually implement some of them yourself if you wish - at least until we have some official ones out.
     
  7. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,532
    I figured this was probably the case. Thanks for the info!
     
  8. TruongNguyenTungDuy

    TruongNguyenTungDuy

    Joined:
    Oct 27, 2017
    Posts:
    13
    Try this, it work for me :)
    Code (CSharp):
    1. Editor editor = Editor.CreateEditor(component);
    2. IMGUIContainer inspectorIMGUI = new IMGUIContainer(() => { editor.OnInspectorGUI(); });
     
  9. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,532
    I ended up drawing the properties individually by iterating through the SerializedObject.

    I should probably have supported drawing the Editor, since now
    PropertyDrawer
    s work but
    CustomEditor
    s will not work. However I needed some things like the missing decorators and stuff to work so for now thats what it is. I'll probably spend some time to find a better way later.

    It did turn out to work just fine and mimics the inspector just fine which is what I wanted for this database item editor.

    There are a couple of bugs I found on the way, though. For instance Disabled field references (m_script here) apparently can't be clicked to find the script reference asset.

    Heres the relevant code.
    Code (CSharp):
    1.         private static void BuildInspectorProperties(SerializedObject obj, VisualElement container)
    2.         {
    3.             // TODO [Header()] and [Space()] are manually added until Unity supports them.
    4.  
    5.             SerializedProperty iterator = obj.GetIterator();
    6.             Type targetType = obj.targetObject.GetType();
    7.             List<MemberInfo> members = new List<MemberInfo>(targetType.GetMembers());
    8.  
    9.             if (!iterator.NextVisible(true)) return;
    10.             do
    11.             {
    12.                 PropertyField propertyField = new PropertyField(iterator.Copy())
    13.                 {
    14.                     name = "PropertyField:" + iterator.propertyPath
    15.                 };
    16.  
    17.                 MemberInfo member = members.Find(x => x.Name == propertyField.bindingPath);
    18.                 if (member != null)
    19.                 {
    20.                     IEnumerable<Attribute> headers = member.GetCustomAttributes(typeof(HeaderAttribute));
    21.                     IEnumerable<Attribute> spaces = member.GetCustomAttributes(typeof(SpaceAttribute));
    22.  
    23.                     foreach (Attribute x in headers)
    24.                     {
    25.                         HeaderAttribute actual = (HeaderAttribute) x;
    26.                         Label header = new Label { text = actual.header};
    27.                         header.style.unityFontStyleAndWeight = FontStyle.Bold;
    28.                         container.Add(new Label { text = " ", name = "Header Spacer"});
    29.                         container.Add(header);
    30.                     }
    31.                     foreach (Attribute unused in spaces)
    32.                     {
    33.                         container.Add(new Label { text = " " });
    34.                     }
    35.                 }
    36.  
    37.                 if (iterator.propertyPath == "m_Script" && obj.targetObject != null)
    38.                 {
    39.                     propertyField.SetEnabled(value: false);
    40.                 }
    41.  
    42.                 container.Add(propertyField);
    43.             }
    44.             while (iterator.NextVisible(false));
    45.         }
    And it working in action...
    ezgif.com-video-to-gif.gif
     
    Kasfan and CxydaIO like this.
  10. EyasSH

    EyasSH

    Joined:
    Aug 15, 2020
    Posts:
    15
    Sorry to resurrect this thread, but I have a question here -- when you say it still uses the IMGUI default inspector by default, do you mean that:
    - Custom Editors that use UIElements would not use IMGUI? or
    - There's a way to change the default behavior to stop using IMGUI?

    EDIT: Just did some quick editing and saw that implementing my own edtior's CreateInspectorGUI() resulted in the UIElements verison being called!
     
    Last edited: Sep 14, 2020
    ModLunar likes this.
  11. ggzerosum

    ggzerosum

    Joined:
    Sep 26, 2017
    Posts:
    33
    Simple, best solution until now. Thank you for sharing.
     
  12. marcospgp

    marcospgp

    Joined:
    Jun 11, 2018
    Posts:
    194
    Since this is the first result on Google, this is how to populate the default inspector in UI Toolkit:

    InspectorElement.FillDefaultInspector(yourContainer, this.serializedObject, this);


    As seen here under
    Car_Inspector.cs
    .

    Also, why pass in both
    this
    and
    this.serializedObject
    ??
     
    Baste, quibit, Fep310 and 1 other person like this.
  13. Eristen

    Eristen

    Joined:
    Jun 17, 2021
    Posts:
    17
    Hi. I noticed populating the default inspector either with the new UIToolkit way or the old DrawDefaultInspector in OnInspectorGUI() way still yields a non-styled version of the gui (see img) when I am overriding the GameObject editor

    upload_2022-12-14_15-52-51.png

    but I want to retain the default inspector styling like so (after which I want to add my own element)
    upload_2022-12-14_15-54-34.png

    Is there any way to accomplish this?
     
  14. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    I don't know if there's a UITK solution for that, but you can use the Editor. finishedDefaultHeaderGUI with IMGUI for that.
     
    Eristen likes this.
  15. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    780
    We don't have a UI Toolkit version of this yet.
     
    Eristen likes this.
  16. Eristen

    Eristen

    Joined:
    Jun 17, 2021
    Posts:
    17
    Sweet, thanks!

    Thanks!
     
  17. Bruno_Vasa_Creative

    Bruno_Vasa_Creative

    Joined:
    Nov 8, 2023
    Posts:
    6
    Worked for me like a charm. Thank you very much.