Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Nesting EditorGUILayout.BeginHorizontal() and EditorGUILayout.BeginVertical() Causing Misalignment

Discussion in 'Editor & General Support' started by stackdynamic, Jan 4, 2019.

  1. stackdynamic

    stackdynamic

    Joined:
    Mar 18, 2018
    Posts:
    13
    I have a simple custom editor window that makes use of the various EditorGUILayout.__blank__Field() functions to serialize some data. Now, this is working perfectly fine and looks nice and pretty after grouping things with calls to GUILayout.BeginHorizontal() like so:
    upload_2019-1-3_23-49-6.png
    However, within some of these horizontal groupings, I want to nest a vertical grouping of horizontal groupings like so:
    upload_2019-1-3_23-44-41.png
    Vertical groupings are circled in blue, while horizontal ones are denoted by the red lines (sorry if it is a bit messy). This was done by simply nesting calls to BeginHorizontal() and BeginVertical() within each other and works fine--however, the alignment is completely out of wack! Is there a way I can get these nested vertical groupings to look nice/align with the other fields? Thanks!
     
    Last edited: Jan 4, 2019
  2. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,449
    I've never had this issue. Can you create a simple example, that we can copy/paste in a project, that shows the problem and post the code?
     
    stackdynamic likes this.
  3. stackdynamic

    stackdynamic

    Joined:
    Mar 18, 2018
    Posts:
    13
    On a related note, tertiary levels of nesting like in this image seem to cause slight vertical misalignment in horizontal groupings (notice how components and UnityEngine.Experimental.Rendering.HDPipeline.VisualEnviroment are grouped together but are slightly misaligned vertically):
    upload_2019-1-3_23-59-50.png
     

    Attached Files:

  4. stackdynamic

    stackdynamic

    Joined:
    Mar 18, 2018
    Posts:
    13
    Absolutely! The following produces the same results for me:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. class Example : EditorWindow {
    5.     [MenuItem("Window/Example")]
    6.     public static void ShowWindow() {
    7.         EditorWindow.GetWindow(typeof(Example));
    8.     }
    9.  
    10.     public void RepeatText(string message, int repeat) {
    11.         for (int i = 0; i < repeat; i++) {
    12.             EditorGUILayout.LabelField(message);
    13.         }
    14.     }
    15.  
    16.     void OnGUI() {
    17.         EditorGUILayout.BeginHorizontal();
    18.         RepeatText("Nested Text", 3);
    19.         EditorGUILayout.BeginVertical();
    20.         RepeatText("Nested Text", 3);
    21.         EditorGUILayout.EndVertical();
    22.         EditorGUILayout.EndHorizontal();
    23.  
    24.         EditorGUILayout.BeginHorizontal();
    25.         RepeatText("Reference Horizontal Text", 3);
    26.         EditorGUILayout.EndHorizontal();
    27.     }
    28. }
    upload_2019-1-4_0-34-7.png
     
    Ash-Blue likes this.
  5. Ash-Blue

    Ash-Blue

    Joined:
    Aug 18, 2013
    Posts:
    102
    Seeing exactly what @stackdynamic is mentioning. This definitely seems like buggy behavior with no way to fix it.
     
  6. mckinnonCT

    mckinnonCT

    Joined:
    Jun 14, 2017
    Posts:
    1
    A bit late but I thought I'd share my findings.
    In order to achieve this, you need to manipulate EditorGUILayout.labelWidth while setting your BeginHorizontal widths to the same value.
    I found as well that if the features in a Horizontal area are too wide to fit in the specified width then they will expand the Horizontal's width to fit themselves.

    Here's an adjusted version of the above sample code to show what I'm talking about. I've added some controls to the top of the window to manipulate the widths of labelWidth and the widths of the Nested Text.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. class Example : EditorWindow
    5. {
    6.     [MenuItem("Window/Example")]
    7.     public static void ShowWindow()
    8.     {
    9.         EditorWindow.GetWindow(typeof(Example));
    10.     }
    11.  
    12.     public void RepeatText(string message, int repeat, int messageWidth = 0)
    13.     {
    14.         for (int i = 0; i < repeat; i++) {
    15.             if (messageWidth > 0) {
    16.                 EditorGUILayout.LabelField(message, EditorStyles.helpBox, GUILayout.Width(messageWidth));
    17.             } else {
    18.                 EditorGUILayout.LabelField(message, EditorStyles.helpBox);
    19.             }
    20.         }
    21.     }
    22.  
    23.     void OnGUI()
    24.     {
    25.         EditorGUILayout.BeginHorizontal("Box");
    26.         DrawControls();
    27.         EditorGUILayout.EndHorizontal();
    28.  
    29.         //Change the label width to whatever your desired width is
    30.         EditorGUIUtility.labelWidth = customLabelWidth;
    31.  
    32.         DrawExampleVariables();
    33.  
    34.         DrawMainExample();
    35.  
    36.         //Reference
    37.         EditorGUILayout.BeginHorizontal("Box");
    38.         RepeatText("Reference Horizontal Text", 3);
    39.         EditorGUILayout.EndHorizontal();
    40.     }
    41.  
    42.     void DrawMainExample()
    43.     {
    44.         Rect r = EditorGUILayout.BeginHorizontal("Box");
    45.         if (autoCalcBoxWidth) {
    46.             //Editor alternates r.width between actual value and 0.
    47.             //Preserve the width
    48.             customLabelWidth = (int)(r.width / 2f) > 0 ? (int)(r.width / 2f) : customLabelWidth;
    49.         }
    50.  
    51.         //Left box
    52.         EditorGUILayout.BeginHorizontal("Box", GUILayout.Width(customLabelWidth));
    53.         if (useCustomTextWidth) {
    54.             RepeatText("Nested Text", repeats, nestedTextWidth);
    55.         } else {
    56.             RepeatText("Nested Text", repeats);
    57.         }
    58.         EditorGUILayout.EndHorizontal();
    59.  
    60.         //Reset the label width for the right box
    61.         EditorGUIUtility.labelWidth = 0;
    62.  
    63.         //Right box
    64.         EditorGUILayout.BeginVertical("Box");
    65.         EditorGUILayout.PrefixLabel("Variable Label", EditorStyles.boldLabel);
    66.         RepeatText("Nested Variable", 4);
    67.         EditorGUILayout.EndVertical();
    68.  
    69.         //Restore the label width
    70.         EditorGUIUtility.labelWidth = customLabelWidth;
    71.  
    72.         EditorGUILayout.EndHorizontal();
    73.     }
    74.  
    75.     void DrawExampleVariables()
    76.     {
    77.         //Filler and example variables
    78.         EditorGUILayout.BeginHorizontal("Box");
    79.         EditorGUILayout.IntField("Short name", 1234);
    80.         EditorGUILayout.EndHorizontal();
    81.  
    82.         //Manipulate wideMode to make sure the vector3 stays on the same line
    83.         EditorGUILayout.BeginHorizontal("Box");
    84.         bool boolHolder = EditorGUIUtility.wideMode;
    85.         EditorGUIUtility.wideMode = true;
    86.         EditorGUILayout.Vector3Field("Medium length name", Vector3.one, GUILayout.ExpandHeight(false));
    87.         EditorGUIUtility.wideMode = boolHolder;
    88.         EditorGUILayout.EndHorizontal();
    89.  
    90.         EditorGUILayout.BeginHorizontal("Box");
    91.         EditorGUILayout.ColorField("An even longer name than before", Color.red);
    92.         EditorGUILayout.EndHorizontal();
    93.  
    94.         EditorGUILayout.BeginHorizontal("Box");
    95.         EditorGUILayout.TextField("Absurdly long name that is most likely never going to fit in any editor window unless you try to get all of this text to show up in which case good job for doing so", "Example text");
    96.         EditorGUILayout.EndHorizontal();
    97.     }
    98.  
    99.     //Control variables
    100.     int customLabelWidth = 350;
    101.     bool useCustomTextWidth = false;
    102.     bool autoCalcBoxWidth = false;
    103.     int nestedTextWidth = 150;
    104.     int repeats = 3;
    105.  
    106.     void DrawControls()
    107.     {
    108.         //How many "Nested Texts" are shown on the left hand side
    109.         EditorGUILayout.LabelField("Repeats", GUILayout.Width(50));
    110.         repeats = EditorGUILayout.IntField(repeats, GUILayout.Width(40));
    111.  
    112.         //Handle the left box's width
    113.         if (!(autoCalcBoxWidth = EditorGUILayout.Toggle("Autocalculate box width", autoCalcBoxWidth, GUILayout.ExpandWidth(false)))) {
    114.             EditorGUIUtility.labelWidth -= 80;
    115.             customLabelWidth = EditorGUILayout.IntField("Box width:", customLabelWidth, GUILayout.ExpandWidth(false));
    116.             EditorGUIUtility.labelWidth += 80;
    117.         } else {
    118.             EditorGUILayout.LabelField("Box width:", GUILayout.Width(75));
    119.             EditorGUILayout.LabelField(customLabelWidth.ToString(), GUILayout.Width(40));
    120.         }
    121.  
    122.         //Whether we can define the length of any "Nested text" field
    123.         if ((useCustomTextWidth = EditorGUILayout.Toggle("Use custom text width", useCustomTextWidth, GUILayout.ExpandWidth(false)))) {
    124.             nestedTextWidth = EditorGUILayout.IntField("Nested Text width:", nestedTextWidth);
    125.         }
    126.     }
    127. }