Got a Problem when serializing Class Dictionary with Custom Editor

Hi there. I’ve got so much frustation while using my Custom Editor.

first, I made a MagicInformation Class for my UI. it contains sprite and values for GUI. and also I used Dictionary for more comfortable management.

and I thought it’ll be nice if I can serialize all of my Classes via Inspector. so I made a Custom Editor for UICore like this Sample Code. (sadly the Codes are not from myself, though.)

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

[CustomEditor(typeof(UICore))]

public class UICoreEditor : Editor {
	public bool Fold = false;
	public string Aditive_Key = "";
	public override void OnInspectorGUI()
	{
		base.OnInspectorGUI ();
		Aditive_Key = EditorGUILayout.TextField ("Input Key", Aditive_Key);
		Dictionary<string, MagicInformation> Dic = (target as UICore).MagicList;

		if (GUILayout.Button ("Add Data", GUILayout.Width (100))) {
			MagicInformation Data = new MagicInformation ();

			if (Dic.ContainsKey (Aditive_Key) == false)
				Dic.Add (Aditive_Key, Data);
			else
				EditorUtility.DisplayDialog ("Error", "Same Key Exists", "Close");
		}

		if (GUILayout.Button ("Delete Value", GUILayout.Width (100))) {

			if (Dic.ContainsKey (Aditive_Key) == true)
				Dic.Remove (Aditive_Key);
			else
				EditorUtility.DisplayDialog ("Error", "No Key Matched", "Close");
		}

		EditorGUILayout.Foldout (Fold, string.Format ("List({0})", Dic.Count));
		{
			foreach (var item in (target as UICore).MagicList) {
				EditorGUILayout.LabelField (item.Key);
				EditorGUILayout.BeginVertical ("Box");
				item.Value.MagicImage = EditorGUILayout.ObjectField ("Sprite", item.Value.MagicImage, typeof(Sprite), false) as Sprite;
				item.Value.MagicName = EditorGUILayout.TextField ("Magic Name", item.Value.MagicName);
				item.Value.MagicCost = EditorGUILayout.IntField ("Magic Cost", item.Value.MagicCost);
				item.Value.MagicDescription = EditorGUILayout.TextField ("Magic Description", item.Value.MagicDescription);
				EditorGUILayout.EndVertical ();
			}
		}
	}
}

and when I checked UICore I got this result.

It seemed works fine, but When I put my values and run a Game, I got an Error message “KeyNotFoundException: The given key was not present in the dictionary.”. and all my values are gone from Inspector.

And I cannot even guess why this happens. I though “EditorGUILayout.Foldout()” function is enough for putting values for my dictionary, but there’s no values. why this keeps happening?

please help me guys… my deadline is coming… :frowning:

Hi @Kazel1873! The problem is Unity cannot serialize Dictionary<TKey, TValue>. When you create those entries in your editor, they only live on that instance until the level changes, the domain is reloaded, the game starts/stops, etc.

You’ll need to do some other stuff to ensure you can’t get duplicate entries and such, but basically what you need to do is:

  1. Make sure MagicInformation is marked with System.SerializableAttribue
  2. Make a KeyedMagicInformation class also marked with System.SerializableAttribute that has a string field and a MagicInformation field
  3. Make a list or array of KeyedMagicInformation on your MonoBehaviour
  4. Revise your custom editor controls as necessary. I would recommend using the ReorderableList widget in UnityEditorInternal
  5. (Optionally) Implement ISerializationCallbackReceiver on your MonoBehaviour to map your KeyedMagicInformation list to a private Dictionary<string, MagicInformation> if required or desirable in your implementation