How to create a custom inspector showing a list of lists in Unity?

10,536

No, You don't need the EditorList.cs.

Demonstration Image

EditorGUILayout.PropertyField has a parameter includeChildren to show its children properties.

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

[CustomEditor(typeof(LevelController))]

public class InspectorCustomizer : Editor
{

    public override void OnInspectorGUI()   
    {
        //DrawDefaultInspector();

        serializedObject.Update();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("Levels"), true);
        serializedObject.ApplyModifiedProperties();
    }
}
Share:
10,536
Nathan Danzmann
Author by

Nathan Danzmann

Updated on June 14, 2022

Comments

  • Nathan Danzmann
    Nathan Danzmann almost 2 years

    well, I'm working on a specific part of a game in which I need to create a list of lists, a list of Game levels and in each list node a list of triggers (The level lists and each list inside it are variable in size). This is all in the script LevelController.cs. This is the Trigger class (it's simple like this for now)

    [System.Serializable]
    public class TriggerClass
    {
    
        public GameObject Trigger;
        public bool Active;
        public int Type;
    
        public TriggerClass(GameObject obje, bool active = false, int type = 1)
        {
            Trigger = obje;
            Active = active;
            Type = type;
        }
    
    }
    

    And a wrapper class to create the Levels List

    [System.Serializable]
    public class WrapperClass
    {
        public List<TriggerClass> Triggers = new List<TriggerClass>();
    }
    

    And of course

    public List<WrapperClass> Levels = new List<WrapperClass>();
    

    I serialized both and they show ok in standard Inspector draw in Unity, but I need to customize the Inspector showing this list, so I made a InspectorCustomizer.cs and a EditorList.cs in Editor folder. For now I'm just trying to simulate the default draw that Unity does with the lists (an expand arrow, a size field that creates that amount of list nodes, and in each node the same thing, as I said, the default that happens if you uncomment the DrawDefaultInspector and comment the other 3 lines in InspectorCustomizer.cs)

    The InspectorCustomizer:

    [CustomEditor(typeof(LevelController))]
    
    public class InspectorCustomizer : Editor
    {
    
        public override void OnInspectorGUI()   
        {
            //DrawDefaultInspector();
    
            serializedObject.Update();
            EditorList.Show(serializedObject.FindProperty("Levels"));
            serializedObject.ApplyModifiedProperties();
        }
    }
    

    And here the EditorList.cs:

    public static class EditorList
    {
        public static void Show (SerializedProperty list)
        {
            EditorGUILayout.PropertyField(list);
            EditorGUI.indentLevel += 1;
            if (list.isExpanded)
            {
                EditorGUILayout.PropertyField(list.FindPropertyRelative("Array.size"));
                for (int i = 0; i < list.arraySize; i++)
                {
                    EditorGUILayout.PropertyField(list.GetArrayElementAtIndex(i));
    
                }
            }
            EditorGUI.indentLevel -= 1;
        }
    }
    

    But this just shows the "Levels" list with empty elements, I click in the expande arrow in each element and nothing shows up, I know this happens because the script is iterating only through the Levels list and not each element within, but I don't know how to iterate through every element inside the Levels list to show the same thing. I'm not really used to serialization so forgive me if this sounds easy.

    I cannot do EditorList.Show(list[i]); inside the for loop because it cannot apply indexing to a serializedProperty of course, so how do I procced?