- Home /
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... :(
Answer by Adam-Mechtley · Oct 03, 2016 at 08:05 PM
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:
Make sure MagicInformation is marked with System.SerializableAttribue
Make a KeyedMagicInformation class also marked with System.SerializableAttribute that has a string field and a MagicInformation field
Make a list or array of KeyedMagicInformation on your MonoBehaviour
Revise your custom editor controls as necessary. I would recommend using the ReorderableList widget in UnityEditorInternal
(Optionally) Implement ISerializationCallbackReceiver on your MonoBehaviour to map your KeyedMagicInformation list to a private Dictionary<string, MagicInformation> if required or desirable in your implementation
Your answer
Follow this Question
Related Questions
SerializedProperty with children class fields 2 Answers
object list not serializing 2 Answers
Saving Game Confussion 1 Answer
ONE monobehaviour, all serialization!? 0 Answers
Save Data from Editor Script, Serialize Nested Class List 1 Answer