Search Unity

Show/ Hide variables in PropertyDrawer

Discussion in 'Immediate Mode GUI (IMGUI)' started by Timbon77, Oct 27, 2020.

  1. Timbon77

    Timbon77

    Joined:
    Oct 3, 2019
    Posts:
    38
    Hi everyone

    I am trying to learn how to use PropertyDrawer and I find it very difficult.
    Right now I just want to get the basic idea of it but evey example that I see is very complicated.
    If anyone can just show me, via code if possible, how can I select a specific variable and hide/show it
     
  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Did you check this page:
    https://docs.unity3d.com/ScriptReference/PropertyDrawer.html

    Simply put, it is pretty similar to creating custom editor, but you can't use automatic layout. So instead of EditorGUILayout you can use EditorGUI and so on.

    So you'll have to place each element using a Rect, to define its position.

    Worst part IMHO is the fact that rect you get in is named as "position"... which is confusing.

    It is also confusing that manual page talks about Property Drawers and PropertyAttributes which are different things IMO, so forget the end part of that page if you are interested in PropertyDrawer.
     
    Last edited: Oct 27, 2020
  3. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    Here is a simplified (and probably not the best) version of what manual shows...

    First you have a MB or Scriptable Object, where you have some typical serializable class or array/list of such type:
    Code (CSharp):
    1. public class TestingPropertyDrawers : MonoBehaviour
    2. {
    3.     public Stuff[] list;
    4. }
    5.  
    6. [System.Serializable]
    7. public class Stuff
    8. {
    9.     public string name;
    10.     public int amount = 1;
    11. }
    12.  
    Then you have the Property Drawer for Stuff:
    Code (CSharp):
    1.  
    2. [CustomPropertyDrawer(typeof(Stuff))]
    3. public class StuffDrawer : PropertyDrawer
    4. {
    5.     public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
    6.     {
    7.         // draw label, it returns modified rect
    8.         rect = EditorGUI.PrefixLabel(rect, new GUIContent("Stuff:"));
    9.  
    10.         // reset indentation
    11.         var indent = EditorGUI.indentLevel;
    12.         EditorGUI.indentLevel = 0;
    13.  
    14.         // New rect for next element
    15.         var amountRect = new Rect(rect.x, rect.y, 80, rect.height);
    16.  
    17.         // draw amount field using amount rect
    18.         EditorGUI.PropertyField(amountRect, property.FindPropertyRelative("amount"), GUIContent.none);
    19.  
    20.         // draw name field, move rect position to right 90 pixels
    21.         var nameRect = new Rect(rect.x + 90, rect.y, 80, rect.height);
    22.         EditorGUI.PropertyField(nameRect, property.FindPropertyRelative("name"), GUIContent.none);
    23.  
    24.         // indent back to where it was
    25.         EditorGUI.indentLevel =  indent;
    26.     }
    27. }
    So basically you get the rect in OnGUI parameters from Unity, then you can use that rect (as starting point) to place Stuff's elements in inspector where Stuff is rendered.

    You place one GUI element, then move down or left or whatever, draw next field and so on. So if you have a list of Stuff, Property Drawer draws its elements in a Rect that draws one Stuff element.

    So stuff will now look like this in my list (actually an array...):
    stuff.PNG
     
    Last edited: Oct 27, 2020
  4. Timbon77

    Timbon77

    Joined:
    Oct 3, 2019
    Posts:
    38
    It is a bit more clear now, but I have still a few questions, is there a way to do it for an Asset Menu ?
    And how do I hide/show a specific variable? I tried to use
    EditorGUI.PropertyField(rect, property.FindPropertyRelative("name"), label, false);
    but it disables the int field at the same time
     
  5. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    "is there a way to do it for an Asset Menu ?"

    I have no idea what you mean by this.

    "And how do I hide/show a specific variable?"

    I think you should read IMGUI code examples a bit more, if you are not familiar with how it works. You create your GUI from your code, hence the immediate mode I guess.

    So if you want some conditional rendering, put it in block below if statement for example. See this: https://docs.unity3d.com/ScriptReference/GUILayout.Button.html

    You can find several examples if you google or do a search here or in the answers.