Search Unity

Bug EditorGUILayout.PropertyField does not always align with EditorGUI.indent

Discussion in 'Immediate Mode GUI (IMGUI)' started by KageKirin, Jun 8, 2022.

  1. KageKirin

    KageKirin

    Joined:
    Jan 22, 2014
    Posts:
    50
    Hi, is this a bug?

    In the image below, you see a custom property drawer implemented for a
    HumanBoneLimit
    class (that mimicks HumanBone, but is serializable).

    The upper 5 sub-property drawers are displayed using EditorGUILayout.PropertyField,
    whereas the the lower 5 sub-property drawers are displayed using EditorGUILayout.Vector3Field, respectively FloatField.

    As observable below, the indent does not match for some of the PropertyFields while it is always correct for the specific type fields.
    upload_2022-6-8_23-56-54.png


    Here's the code for a repro case.

    Code (CSharp):
    1.  
    2. using System.Globalization;
    3. using System.Linq;
    4. using UnityEditor;
    5. using UnityEngine;
    6. using NUnit.Framework;
    7.  
    8. namespace MascotCapsule
    9. {
    10.     [CustomPropertyDrawer(typeof(HumanBoneLimit))]
    11.     public class HumanBoneLimitPropertyDrawer : PropertyDrawer
    12.     {
    13.         bool foldout = false;
    14.  
    15.         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    16.         {
    17.             if (property == null)
    18.                 return;
    19.  
    20.             var p_useDefaultValues = property.FindPropertyRelative("useDefaultValues");
    21.             var p_min = property.FindPropertyRelative("min");
    22.             var p_max = property.FindPropertyRelative("max");
    23.             var p_center = property.FindPropertyRelative("center");
    24.             var p_axisLength = property.FindPropertyRelative("axisLength");
    25.  
    26.             // Create property container element.
    27.             EditorGUI.BeginProperty(position, label, property);
    28.             foldout = EditorGUILayout.BeginFoldoutHeaderGroup(foldout, property.displayName);
    29.             EditorGUILayout.EndFoldoutHeaderGroup();
    30.  
    31.             if (foldout)
    32.             {
    33.                 EditorGUI.indentLevel++;
    34.                 EditorGUILayout.PropertyField(p_useDefaultValues);
    35.                 if (!p_useDefaultValues.boolValue)
    36.                 {
    37.                     EditorGUILayout.PropertyField(p_min, true);
    38.                     EditorGUILayout.PropertyField(p_max, true);
    39.                     EditorGUILayout.PropertyField(p_center, true);
    40.                     EditorGUILayout.PropertyField(p_axisLength, true);
    41.                 }
    42.  
    43.                 p_useDefaultValues.boolValue = EditorGUILayout.Toggle(
    44.                     p_useDefaultValues.displayName,
    45.                     p_useDefaultValues.boolValue
    46.                 );
    47.                 if (!p_useDefaultValues.boolValue)
    48.                 {
    49.                     p_min.vector3Value = EditorGUILayout.Vector3Field(
    50.                         p_min.displayName,
    51.                         p_min.vector3Value
    52.                     );
    53.                     p_max.vector3Value = EditorGUILayout.Vector3Field(
    54.                         p_max.displayName,
    55.                         p_max.vector3Value
    56.                     );
    57.                     p_center.vector3Value = EditorGUILayout.Vector3Field(
    58.                         p_center.displayName,
    59.                         p_center.vector3Value
    60.                     );
    61.                     p_axisLength.floatValue = EditorGUILayout.FloatField(
    62.                         p_axisLength.displayName,
    63.                         p_axisLength.floatValue
    64.                     );
    65.                 }
    66.                 EditorGUI.indentLevel--;
    67.             }
    68.             EditorGUI.EndProperty();
    69.         }
    70.     }
    71. }
    72.  
    For this class
    Code (CSharp):
    1. using System;
    2. using System.Linq;
    3. using System.Collections.Generic;
    4. using System.Runtime.Serialization;
    5. using NUnit.Framework;
    6.  
    7. using UnityEngine;
    8. using UnityEditor;
    9. using Unity.Mathematics;
    10.  
    11. namespace MyProjectNamespace
    12. {
    13.     /// this mimicks HumanLimit in a serializable way
    14.     [Serializable]
    15.     public class HumanBoneLimit
    16.     {
    17.         [SerializeField]
    18.         public bool useDefaultValues;
    19.  
    20.         [SerializeField]
    21.         public float3 min;
    22.  
    23.         [SerializeField]
    24.         public float3 max;
    25.  
    26.         [SerializeField]
    27.         public float3 center;
    28.  
    29.         [SerializeField]
    30.         public float axisLength;
    31.  
    32.         public HumanBoneLimit() { }
    33.  
    34.         public HumanBoneLimit(in HumanLimit humanLimit)
    35.         {
    36.             useDefaultValues = humanLimit.useDefaultValues;
    37.             min = humanLimit.min;
    38.             max = humanLimit.max;
    39.             center = humanLimit.center;
    40.             axisLength = humanLimit.axisLength;
    41.         }
    42.  
    43.         public static explicit operator HumanLimit(in HumanBoneLimit hbl)
    44.         {
    45.             return new HumanLimit()
    46.             {
    47.                 useDefaultValues = hbl.useDefaultValues,
    48.                 min = hbl.min,
    49.                 max = hbl.max,
    50.                 center = hbl.center,
    51.                 axisLength = hbl.axisLength,
    52.             };
    53.         }
    54.     }
    55. }
    56.  
    This looks to me like some incoherence in the property drawer, but please advice me if I'm doing something wrong in the display code.

    Cheers.
     

    Attached Files: