- Home /
 
Custom Editor for Map/Dictionary in Unity
I'm trying to build my own little ResourceManager in Unity that will allow me to tag resources (ranging from materials to prefabs) to a label in the editor, and then access them in game.
The ResourceManager itself is really easy to write- it's just a Dictionary. However the Unity Editor doesn't seem to be able to serialize (and thus render) Dictionaries.
To get around this, I created a list of key-value pairs which gets loaded into the dictionary by unity. That way Unity gets its list and I get my Dictionary. However, when I try and run the code shown below, I can only add a single entry to the list. Any idea what I'm doing wrong?
ResourceManager.cs
     using UnityEngine;
     using System.Collections.Generic;
     
     public class ResourceManager : MonoBehaviour, ISerializationCallbackReceiver {
         private Dictionary<string, Object> resources = new Dictionary<string, Object>();
     
         #region Unity
         // Unity doesn't know how to deal with maps, so we give it a list to work with
         public List<ResourceEntry> entries;
     
         // Dictionary -> List
         public void OnBeforeSerialize() {
             entries.Clear();
             foreach(string key in resources.Keys) {
                 entries.Add(new ResourceEntry(key, resources[key]));
             }
         }
     
         // List -> Dictionary
         public void OnAfterDeserialize() {
             resources = new Dictionary<string, Object>();
             foreach(ResourceEntry entry in entries) {
                 resources[entry.key] = entry.value;
             }
         }
     
         [System.Serializable]
         public class ResourceEntry {
             public string key;
             public Object value;
             
             public ResourceEntry() {}
             
             public ResourceEntry(string key, Object value) {
                 this.key = key;
                 this.value = value;
             }
         }
         #endregion
     
         private static ResourceManager instance;
         public static Object Get(string category, string key) {
             instance = instance ?? GameObject.FindObjectOfType<ResourceManager>();
             if( instance.resources.ContainsKey(key)) {
                 return instance.resources[key];
             } else {
                 return null;
             }
         }
     }
 
 ResourceManagerEditor.cs
 
     using UnityEngine;
     using System.Collections.Generic;
     using UnityEditor;
     using UnityEditorInternal;
     
     [CustomEditor(typeof(ResourceManager))]
     public class ResourceManagerEditor : Editor {
         private ReorderableList list;
     
         public void OnEnable() {
             list = new ReorderableList(serializedObject, serializedObject.FindProperty("entries"), true, true, true, true);
             list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
                 SerializedProperty element = list.serializedProperty.GetArrayElementAtIndex(index);
                 rect.y += 2;
                 EditorGUI.PropertyField(new Rect(rect.x, rect.y, 60, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative("key"), GUIContent.none);
                 EditorGUI.PropertyField(new Rect(rect.x + 70, rect.y, 160, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative("value"), GUIContent.none);
             };
             list.drawHeaderCallback = (Rect rect) => {
                 EditorGUI.LabelField(rect, "Resources");
             };
         }
     
         public override void OnInspectorGUI() {
             serializedObject.Update();
             list.DoLayoutList();
             serializedObject.ApplyModifiedProperties();
         }
     }
 
              Your answer
 
             Follow this Question
Related Questions
Dictionary in inspector 4 Answers
CustomEditor for 2 List to look like dictionary 1 Answer
Scriptable Object resets after Unity is closed 2 Answers
Dictionairy Serialization Problem: Keys and values get lost 0 Answers
Is EditorUtility.SetDirty restricted to prefabs or inspected GameObject? 5 Answers