Custom Inspector: Making Individual Vertical Containers and Dynamically Adding & Removing Child Elements

TL;DR: How can one make individual containers that display their child elements vertically inside them?

(I.e: Array of elements shown as menu items)

Hello everybody,

In the example (provided in attachment), what I am trying to achieve is to dynamically add and remove buttons to corresponding “lists”. From enum popup, I make a selection and click “Add”, it is supposed to add to red, yellow or green list based on selection. "Some Button"s created in the code are where they are supposed to be. But adding buttons via loop like I did in the code well, script adds new buttons after Red List label, no matter the current selection is.

I tried working with some examples I found online. Tried using EditorGUILayout.BeginVertical(), and EditorGUILayoutEndVertical(). Couldn’t make much sense about using them.

Main question: How can properly group these dynamically added & removed buttons?

using UnityEditor;
using UnityEngine.SceneManagement;
using UnityEditor.SceneManagement;
using System.Collections;
using System.Collections.Generic;

[CustomEditor(typeof(SomeScript))]
[CanEditMultipleObjects]
public class SomeScriptCustomInspector : Editor
{
    public SScript.LineItem LineItemType;
   
    public override void OnInspectorGUI()
    {
        SomeScript sScript = (SomeScript)target;

        #region StaticSection
        if (GUILayout.Button("Add New"))
        {
            TriggerEditorLibrary.AddNewLine(sScript, LineItemType);
        }

        LineItemType = (SScript.LineItem)EditorGUILayout.EnumPopup(LineItemType);

        if (GUILayout.Button("Delete All"))
        {
            sScript.ScriptLines.Clear();
        }
        #endregion

        #region Red
        GUILayout.Label("Red List");
        GUI.color = new Color(255, 0, 0);

        GUILayout.Button("Some Button");
        GUILayout.Button("Some Button");

        if (sScript.ScriptLines.Count != 0)
        {
            foreach (SScript element in sScript.ScriptLines)
            {
                if (element.LineItemType == SScript.LineItem.Red)
                {
                    GUILayout.Button(element.Name);
                }
            }
        }
        #endregion

        #region Yellow
        GUILayout.Label("Yellow List");
        GUI.color = new Color(255, 255, 0);

        GUILayout.Button("Some Button");
        GUILayout.Button("Some Button");

        if (sScript.ScriptLines.Count != 0)
        {
            foreach (SScript element in sScript.ScriptLines)
            {
                if (element.LineItemType == SScript.LineItem.Yellow)
                {
                    GUILayout.Button(element.Name);
                }
            }
        }
        #endregion

        #region Green
        GUILayout.Label("Green List");
        GUI.color = new Color(0, 255, 0);

        GUILayout.Button("Some Button");
        GUILayout.Button("Some Button");

        if (sScript.ScriptLines.Count != 0)
        {
            foreach (SScript element in sScript.ScriptLines)
            {
                if (element.LineItemType == SScript.LineItem.Green)
                {
                    GUILayout.Button(element.Name);
                }
            }
        }
        #endregion

        if (GUI.changed)
        {
            EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
        }
    }

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[System.Serializable]
public class SScript
{
    public string Name = "";
    public enum LineItem { Red, Yellow, Green }
    public LineItem LineItemType;
}

public class SomeScript : MonoBehaviour
{

    public List<SScript> ScriptLines;
}

using UnityEditor;
using System.Collections;

public static class TriggerEditorLibrary
{

    public static void AddNewLine(Trigger target, ScriptLine.LineItem lineItemType)
    {
        ScriptLine newScriptLine = new ScriptLine();
        newScriptLine.Name = "New " + lineItemType.ToString();
        target.ScriptLines.Add(newScriptLine);
    }
}

Your static AddNewLine method does not set the new object’s LineItemType. You need this line as well:

newScriptLine.LineItemType = lineItemType;