How to show a static List in Unity Inspector

Hey everyone,

I thought this was really cool So I decided to post up what I did.

I wanted to make the List static but readable in the inspector. Here’s how I did it.

Pre Reqs:

The Code below will work for displaying my PanelPositionManager List of PanelContainers:
PanelsPositionManager.cs

using System.Collections.Generic;
using UnityEngine;

public class PanelsPositionManager : MonoBehaviour
{
    #region Static Vars
    public static PanelsPositionManager instance
    {
        get
        {
            if (_instance == null)
                _instance = GameObject.FindObjectOfType<PanelsPositionManager>();
            return _instance;
        }
    }
    private static PanelsPositionManager _instance;
    #region Panel Container List Management
    public static List<PanelContainer> panelContainers
    {
        get
        {
            if (_panelContainers == null)
                PanelsPositionManager.instance.GetAllChildrenPanelContainers();
            else if (_panelContainers.Count != PanelsPositionManager.instance.transform.GetComponentsInChildren<PanelContainer>().Length)
                PanelsPositionManager.instance.GetAllChildrenPanelContainers();
            return _panelContainers;
        }
    }
    public static List<PanelContainer> _panelContainers;
    public List<PanelContainer> _panelContainersDisplay;
    void GetAllChildrenPanelContainers()
    {
        PanelContainer[] containers = GetComponentsInChildren<PanelContainer>();
        if (_panelContainers == null)
            _panelContainers = new List<PanelContainer>();
        else if (_panelContainers.Count > 0)
            _panelContainers.Clear();
        _panelContainers.AddRange(containers);
        if (_panelContainersDisplay == null)
            _panelContainersDisplay = new List<PanelContainer>();
        else if (_panelContainersDisplay.Count > 0)
            _panelContainersDisplay.Clear();
        _panelContainersDisplay.AddRange(containers);
    }

    internal static void RegisterPanelContainer(PanelContainer panelContainer)
    {
        _panelContainers.Add(panelContainer);
    }

    internal static void UnRegisterPanelContainer(PanelContainer panelContainer)
    {
        _panelContainers.Remove(panelContainer);
    }

    internal static void ClearPanelList()
    {
        _panelContainers.Clear();
    }
    #endregion
    #endregion
}

PanelContainer.cs

using UnityEngine;

public class PanelContainer : MonoBehaviour
{
}

PanelsPositionManagerEditor.cs

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

[CustomEditor(typeof(PanelsPositionManager))]
public class PanelsPositionManagerEditor : Editor
{
    PanelsPositionManager _target;
    private ReorderableList list;
    bool populateList = false;
    // Use this for initialization
    public override void OnEnable()
    {
        base.OnEnable();
        _target = (PanelsPositionManager)target;
        populateList = (PanelsPositionManager.panelContainers.Count > 0) ? true : false;
        if (populateList)
        {
            list = new ReorderableList(serializedObject,
                   serializedObject.FindProperty("_panelContainersDisplay"),
                   true, true, true, true);
            list.drawHeaderCallback = (Rect rect) =>
            {
                EditorGUI.LabelField(rect, "Panels in Container");
            };
            list.drawElementCallback =
        (Rect rect, int index, bool isActive, bool isFocused) =>
        {
            var element = list.serializedProperty.GetArrayElementAtIndex(index);
            rect.y += 2;
            EditorGUI.PropertyField(
                new Rect(rect.x, rect.y, Screen.width*.8f, EditorGUIUtility.singleLineHeight),
                element, GUIContent.none);
        };

            list.onAddCallback = (ReorderableList l) =>
            {
                var index = l.serializedProperty.arraySize;
                l.serializedProperty.arraySize++;
                l.index = index;
                var element = l.serializedProperty.GetArrayElementAtIndex(index);
            };
        }
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

         EditorGUI.BeginChangeCheck()
        //UI Elements for modifying Serialized Properties
        if(EditorGUI.EndChangeCheck())
       {
        serializedObject.ApplyModifiedProperties();
        //Run Operations to update values in script and associated elements
        }
        //Display List
        if (populateList)
        {
            list.DoLayoutList();
        }
    }
}

Results:

5 Likes

Awesome

Thanks, this is useful. However, in every script reload (serialization), static list elements disappear. Can you suggest any solution to that?

Because static data does actually disappear on domain reloads. Recommendation is to store your data in a ScriptableObject instead of static fields if you want Unity to save it.

1 Like

Thanks :slight_smile: