Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. We're looking for your feedback on the platforms you use and how you use them. Let us know!
    Dismiss Notice
  4. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  6. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  7. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  8. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Combining foldout and fields

Discussion in 'Extensions & OnGUI' started by Estecka, Jul 25, 2018.

  1. Estecka

    Estecka

    Joined:
    Oct 11, 2013
    Posts:
    51
    It's not unusual when I I create a custom PropertyDrawer with folded properties, that I still want to draw a field (the most significant one) right in front of the foldout, so it can be accessed even when the property is folded :
    foldout.gif
    I find this looks nice, but I'm starting to get several issues with this layout.

    Here's a simple code that does just that, put a foldout arrow in front of a property :
    Code (CSharp):
    1. [CustomPropertyDrawer(typeof(KeyCode))]
    2. public class KeycodeDrawer : PropertyDrawer {
    3.     public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
    4.  
    5.         Rect foldoutPos = position;
    6.         //foldoutPos.width = 0;
    7.         property.isExpanded = EditorGUI.Foldout (foldoutPos, property.isExpanded, GUIContent.none);
    8.  
    9.         EditorGUI.PropertyField (position, property);
    10.  
    11.     }//
    12.  
    13. } // END Drawer
    If you run the code as is, the foldout arrow will work just fine, but you won't be able to select a keycode from the popup menu, like the foldout is blocking the way.
    The solution I had found to this is the commented line in the code above: setting the foldout's width to Zero.

    Now everything works nicely... or so it seems. From this solution arises issue n°2 :
    If you try making an array of keycode, instead of a single field, then the foldout arrow can no longer be clicked anymore.
     
  2. Estecka

    Estecka

    Joined:
    Oct 11, 2013
    Posts:
    51
    So, where does the inconsistency between array/single property come from ?
    And why does the foldout prevent from using its assigned rect, when it's not actually using this rect for anything ?
     
  3. PsyKaw

    PsyKaw

    Joined:
    Aug 16, 2012
    Posts:
    86
    Your foldout is too big. Try something like this:
    Code (CSharp):
    1. foldoutPos.width = EditorGUIUtility.labelWidth;
    instead of foldoutPos.width = 0;
    So the foldout interaction is only on the label of the property and you should interact with your property and foldout too.
     
    Estecka likes this.
  4. Estecka

    Estecka

    Joined:
    Oct 11, 2013
    Posts:
    51
    I eventually figured out what it is that makes array work differently from single property :
    EditorGUI.indentLevel
    is set to 1 in array and 0 otherwise.

    Apparently, every single control you draw will automatically be indented, so if you draw multiple controls on the same line, they will all have their own little indentation.
    (Their left bound will be moved to the right, but their right bound stays where it is, hence my zero-sized foldout arrow ends up with a negative width.)

    So the solution to draw everything at the exact place and with the exact size that you asked is to start the property drawer with either :
    Code (CSharp):
    or
    Code (CSharp):
    Depending on what you're drawing

    I knew this was a thing with EditorGUILayout, but I did not expect EditorGUI to interact this way with the indentation. (Until now I believed that the position parameter provided to OnGUI was already pre-indented.)