- Home /
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);
}
}
If you mean whether I can debug.log ScriptLines for checking validity of them, then yes. Also I've added SScript code to my post as well.
if (GUILayout.Button("Add New"))
{
TriggerEditorLibrary.AddNewLine(sScript, LineItemType);
}
LineItemType = (SScript.LineItem)EditorGUILayout.EnumPopup(LineItemType);
...
}
I guess, it might not matter across multiple updates, but it seems odd to me that you are adding the new line, via the TriggerEditorLibraryClass, BEFORE you get the current LineItemType.
I would call that function after getting the LineItemType (store the button return value in a bool, and check that bool and if true, call the TriggerEditorLibraryClass function, AFTER the EnumPopup line)
I think we will need to see the function TriggerEditorLibrary.AddNewLine(sScript, LineItemType); Other than the above possible-issue, the posted GUI code doesn't seem to explain why new items always get added to "red".
I've attached the piece of code that is TriggerEditorLibrary to the end of my post just now.
Answer by Bunny83 · Sep 06, 2016 at 08:25 AM
Your static AddNewLine method does not set the new object's LineItemType. You need this line as well:
newScriptLine.LineItemType = lineItemType;
Thank you for pointing it out :) Though It was a shame that I had to waste time of people with such a trivial mistake.
Your answer
Follow this Question
Related Questions
Edit an object in isolation quickly, as in the new Prefab Mode 0 Answers
Update custom editor based on choosen options 0 Answers
How can i get SerializedProperty from UnityEvent which in List. Sorry for my Eng. 2 Answers
Using EditorGUILayout in my PropertyDrawer for an attribute causes ArgumentException 1 Answer
How can i create a button in a custom class with UnityEditor using custom editor? 0 Answers