Search Unity

How to show a static List in Unity Inspector

Discussion in 'Scripting' started by SolleXelloS, May 3, 2017.

?

Did you find this helpful?

  1. Yes

  2. No

  3. There could have been more information

  4. There was just enough information

Multiple votes are allowed.
Results are only viewable after voting.
  1. SolleXelloS

    SolleXelloS

    Joined:
    Aug 30, 2010
    Posts:
    18
    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:
    1. Knowledge of Editor Scripting
    2. Knowledge of Reorderable Lists
    3. C# Accessors
    The Code below will work for displaying my PanelPositionManager List of PanelContainers:
    PanelsPositionManager.cs
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. public class PanelsPositionManager : MonoBehaviour
    5. {
    6.     #region Static Vars
    7.     public static PanelsPositionManager instance
    8.     {
    9.         get
    10.         {
    11.             if (_instance == null)
    12.                 _instance = GameObject.FindObjectOfType<PanelsPositionManager>();
    13.             return _instance;
    14.         }
    15.     }
    16.     private static PanelsPositionManager _instance;
    17.     #region Panel Container List Management
    18.     public static List<PanelContainer> panelContainers
    19.     {
    20.         get
    21.         {
    22.             if (_panelContainers == null)
    23.                 PanelsPositionManager.instance.GetAllChildrenPanelContainers();
    24.             else if (_panelContainers.Count != PanelsPositionManager.instance.transform.GetComponentsInChildren<PanelContainer>().Length)
    25.                 PanelsPositionManager.instance.GetAllChildrenPanelContainers();
    26.             return _panelContainers;
    27.         }
    28.     }
    29.     public static List<PanelContainer> _panelContainers;
    30.     public List<PanelContainer> _panelContainersDisplay;
    31.     void GetAllChildrenPanelContainers()
    32.     {
    33.         PanelContainer[] containers = GetComponentsInChildren<PanelContainer>();
    34.         if (_panelContainers == null)
    35.             _panelContainers = new List<PanelContainer>();
    36.         else if (_panelContainers.Count > 0)
    37.             _panelContainers.Clear();
    38.         _panelContainers.AddRange(containers);
    39.         if (_panelContainersDisplay == null)
    40.             _panelContainersDisplay = new List<PanelContainer>();
    41.         else if (_panelContainersDisplay.Count > 0)
    42.             _panelContainersDisplay.Clear();
    43.         _panelContainersDisplay.AddRange(containers);
    44.     }
    45.  
    46.     internal static void RegisterPanelContainer(PanelContainer panelContainer)
    47.     {
    48.         _panelContainers.Add(panelContainer);
    49.     }
    50.  
    51.     internal static void UnRegisterPanelContainer(PanelContainer panelContainer)
    52.     {
    53.         _panelContainers.Remove(panelContainer);
    54.     }
    55.  
    56.     internal static void ClearPanelList()
    57.     {
    58.         _panelContainers.Clear();
    59.     }
    60.     #endregion
    61.     #endregion
    62. }
    PanelContainer.cs
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class PanelContainer : MonoBehaviour
    4. {
    5. }
    PanelsPositionManagerEditor.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditorInternal;
    3. using UnityEditor;
    4. using System.Collections.Generic;
    5.  
    6. [CustomEditor(typeof(PanelsPositionManager))]
    7. public class PanelsPositionManagerEditor : Editor
    8. {
    9.     PanelsPositionManager _target;
    10.     private ReorderableList list;
    11.     bool populateList = false;
    12.     // Use this for initialization
    13.     public override void OnEnable()
    14.     {
    15.         base.OnEnable();
    16.         _target = (PanelsPositionManager)target;
    17.         populateList = (PanelsPositionManager.panelContainers.Count > 0) ? true : false;
    18.         if (populateList)
    19.         {
    20.             list = new ReorderableList(serializedObject,
    21.                    serializedObject.FindProperty("_panelContainersDisplay"),
    22.                    true, true, true, true);
    23.             list.drawHeaderCallback = (Rect rect) =>
    24.             {
    25.                 EditorGUI.LabelField(rect, "Panels in Container");
    26.             };
    27.             list.drawElementCallback =
    28.         (Rect rect, int index, bool isActive, bool isFocused) =>
    29.         {
    30.             var element = list.serializedProperty.GetArrayElementAtIndex(index);
    31.             rect.y += 2;
    32.             EditorGUI.PropertyField(
    33.                 new Rect(rect.x, rect.y, Screen.width*.8f, EditorGUIUtility.singleLineHeight),
    34.                 element, GUIContent.none);
    35.         };
    36.  
    37.             list.onAddCallback = (ReorderableList l) =>
    38.             {
    39.                 var index = l.serializedProperty.arraySize;
    40.                 l.serializedProperty.arraySize++;
    41.                 l.index = index;
    42.                 var element = l.serializedProperty.GetArrayElementAtIndex(index);
    43.             };
    44.         }
    45.     }
    46.  
    47.     public override void OnInspectorGUI()
    48.     {
    49.         base.OnInspectorGUI();
    50.  
    51.          EditorGUI.BeginChangeCheck()
    52.         //UI Elements for modifying Serialized Properties
    53.         if(EditorGUI.EndChangeCheck())
    54.        {
    55.         serializedObject.ApplyModifiedProperties();
    56.         //Run Operations to update values in script and associated elements
    57.         }
    58.         //Display List
    59.         if (populateList)
    60.         {
    61.             list.DoLayoutList();
    62.         }
    63.     }
    64. }
    65.  
    Results:
     
    Last edited: May 5, 2017
  2. GuruNYC

    GuruNYC

    Joined:
    Dec 1, 2015
    Posts:
    4
    Awesome
     
  3. Danixadem

    Danixadem

    Joined:
    Jul 31, 2018
    Posts:
    16
    Thanks, this is useful. However, in every script reload (serialization), static list elements disappear. Can you suggest any solution to that?
     
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,911
    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.
     
    laurentlavigne likes this.
  5. Danixadem

    Danixadem

    Joined:
    Jul 31, 2018
    Posts:
    16
    Thanks :)