using System; using System.Collections.Generic; using System.Runtime.Serialization; using UnityEngine; using UnityEngine.Serialization; namespace MoreMountains.Tools { /// /// A serializable dictionary implementation, as Unity still can't serialize Dictionaries natively /// /// How to use : /// /// For each type of dictionary you want to serialize, create a serializable class that inherits from MMSerializableDictionary, /// and override the constructor and the SerializationInfo constructor, like so (here with a string/int Dictionary) : /// /// [Serializable] /// public class DictionaryStringInt : MMSerializableDictionary /// { /// public DictionaryStringInt() : base() { } /// protected DictionaryStringInt(SerializationInfo info, StreamingContext context) : base(info, context) { } /// } /// /// /// /// [Serializable] public class MMSerializableDictionary : Dictionary, ISerializationCallbackReceiver { [SerializeField] protected List _keys = new List(); [SerializeField] protected List _values = new List(); public MMSerializableDictionary() : base() { } public MMSerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { } /// /// We save the dictionary to our two lists /// public void OnBeforeSerialize() { _keys.Clear(); _values.Clear(); foreach (KeyValuePair pair in this) { _keys.Add(pair.Key); _values.Add(pair.Value); } } /// /// Loads our two lists to our dictionary /// /// public void OnAfterDeserialize() { this.Clear(); if (_keys.Count != _values.Count) { Debug.LogError("MMSerializableDictionary : there are " + _keys.Count + " keys and " + _values.Count + " values after deserialization. Counts need to match, make sure both key and value types are serializable."); } for (int i = 0; i < _keys.Count; i++) { this.Add(_keys[i], _values[i]); } } } }