Unity does not support serializing Dictionary types out of the box because it does not handle generic types directly. To make a dictionary serializable in the Inspector, you must create a custom class that inherits from Dictionary and implements the ISerializationCallbackReceiver interface.
This custom class uses two hidden [SerializeField] lists (one for keys and one for values) to store the data, converting the dictionary into a format Unity can save. You must then define specific concrete subclasses (e.g., SerializableDictionary<string, int>) to work with your desired key and value types.
Implementation Pattern
The standard approach involves implementing OnBeforeSerialize to populate the lists from the dictionary and OnAfterDeserialize to reconstruct the dictionary from the lists.
using System;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver
{
[SerializeField]
private List<TKey> keys = new List<TKey>();
[SerializeField]
private List<TValue> values = new List<TValue>();
// Convert dictionary to lists for Unity serialization
public void OnBeforeSerialize()
{
keys.Clear();
values.Clear();
foreach (var pair in this)
{
keys.Add(pair.Key);
values.Add(pair.Value);
}
}
// Rebuild dictionary from lists after deserialization
public void OnAfterDeserialize()
{
this.Clear();
if (keys.Count != values.Count)
{
throw new System.Exception("There are " + keys.Count + " keys and " + values.Count + " values after deserialization. Make sure that both key and value types are serializable.");
}
for (int i = 0; i < keys.Count; i++)
{
this.Add(keys[i], values[i]);
}
keys.Clear();
values.Clear();
}
}
// Concrete subclass required because Unity cannot serialize generic types directly
[System.Serializable]
public class StringIntDictionary : SerializableDictionary<string, int>
{
}Alternative Solutions
Odin Inspector: The Odin Inspector asset automatically serializes dictionaries by inheriting from
SerializedScriptableObjector using their serializer without custom code.SerializedDictionary Package: A popular third-party asset (e.g.,
AYellowpaper.SerializedCollections) provides aSerializedDictionary<,>class that feels native to the Unity Editor and supports features like duplicate keys and bulk editing.JSON Serialization: For runtime-only scenarios, you can serialize the dictionary to a JSON string using
JsonUtility(with a wrapper class) orJson.NET(Newtonsoft), though this does not show in the Inspector by default.Custom Property Drawer: You can create a custom
PropertyDrawerto draw aDictionaryin the Inspector manually, allowing editing without changing the underlying data structure to a serializable list.
Dictionaries are just better resilent arrays with a search complexity O(1). I was working with scriptable objects and found out the hard way that unity doesnt save variables in scriptable objects that cannot be serialized. Had to use Odin Inspector's custom scriptable object for a quick workaround.
I'm sure theres a good reason to not serialize dictionaries... but cant think of any reason not to.