After updating Unity from 5.4.2f1 to 5.5.0f3, large portions of our serialized game data are lost. Investigation revealed that our Serializable classes descending from Dictionary are no longer serialized. The objects do not display in the inspector at all, and their properties are all null or default values when accessed from script (their previously assigned values are gone).
These classes worked fine in all other Unity 5.x versions. This is a rather critical issue for us, since our content format relies heavily on dictionaries. Any chance this would be fixed in an upcoming patch?
Try deleting your Library folder (after closing Unity and backing up the project). Unity will rebuild it next time you open the project, and it will sometimes, but not always, fix issues like this.
Assuming suggestion to nuke library folder doesnât workâŚ
Standard approach is to make your classes implement ISerializationCallbackReceiver interface.|
To my knowledge, dictionaries never worked and were never properly serialized sincce 5.0 and up to 5.3.3, and normally required something like this:
[System.Serializable]
//public class SerialDictionary<Key, Value>: Dictionary<Key, Value>, ISerializationCallbackReceiver{
public class SerialDictionary<Key, Value>: SortedDictionary<Key, Value>, ISerializationCallbackReceiver{
[SerializeField]
List<Key> serialKeys = new List<Key>();
[SerializeField]
List<Value> serialValues = new List<Value>();
public void OnAfterDeserialize(){
base.Clear();
if(serialKeys.Count != serialValues.Count){
throw new System.Exception(
string.Format("there are {0} keys and {1} values after deserialization. Lengths do not match.", serialKeys.Count, serialValues.Count));
}
for (int i = 0; i < serialKeys.Count; i++){
var newKey = serialKeys[i];
var newValue = serialValues[i];
base[newKey] = newValue;
}
}
public void OnBeforeSerialize(){
serialKeys.Clear();
serialValues.Clear();
var tmpKeys = base.Keys;
foreach(var curKey in tmpKeys){
serialKeys.Add(curKey);
serialValues.Add(base[curKey]);
}
}
}
i have the same problem, a non unity [Serializable] class doesnât keep its value anymore, just resets to its defaults (interestingly except some fields with unity object references, like meshes and materials, not consistently though). I dont want to implement ISerializationCallbackReceiver for something that worked implicitly before (and still should).
Maybe Iâm missing something, but dictionaries have never been serialized by Unity, so this sounds much more like code on your side broke than on their side.
Itâs a custom implementation that already uses the ISerializationCallbackReceiver, but your post helped solve the problem nonetheless. I tried changing the base class from Dictionary to SortedDictionary, as shown in the code you posted, and the serialization now works as expected again. This doesnât break anything in our projects, since SortedDictionary uses an identical interface to Dictionary.
The regression in Unity is still present (classes no longer serialize if they inherit from Dictionary<TKey, TValue>), but this is an easy way to work around it, so the issue is resolved well enough for our case.
That doesnât matter. The contents of a dictionary arenât serialized, period. It doesnât matter if the contents are floats or some UnityEngine.Object. Dictionaries are useless in the editor, unless there was a third party asset serializing things on the backend.
if you inherit from a nonserializable class, your additional fields, if public or attributed accordingly can still serialize, if not that must have changed as it definitely worked for me before.
I think you might be hitting some confusion because of how I phrased the issue. When I said âour Serializable classes descending from Dictionary,â I was referring to custom classes that extend the Dictionary class. The content types contained in the Dictionary are not relevant here, as long as the key and value types are both serializable.
btw, i tracked down my issue, my classes donât serialize/track changes (even with custom setDirty etc) if i use a CustomEditor for the containing ScriptableObject.
The reason why I used SortedDictionary in the first place is because in one of the earlier versions of unity using Dictionary in conjunction with ISerializationCallbackReceiver somehow made the project prone to crashing. I never bothered to investigate the reason deeper.