I’m trying to serialize a generic class by creating special subclasses as mentioned in many placed (even the documentation for UnityEvent) but it’s not working as expected.
[Serializable]
public class SceneData
{
// Need to create subclasses to be able to serialize
[Serializable]
private class PersistentBoolCollection : PersistentItemDataCollection<bool> { }
[SerializeField]
private PersistentBoolCollection persistentBools;
}
[Serializable]
public class PersistentItemDataCollection<T> : ISerializationCallbackReceiver
where T : struct
{
// Use special data type for serialization
[Serializable]
private struct SerializableItemData
{
public string SceneName;
public string ID;
public T Value;
}
[SerializeField]
private List<SerializableItemData> serializedList = new List<SerializableItemData>();
[NonSerialized]
private Dictionary<string, Dictionary<string, PersistentItemData<T>>> scenes
= new Dictionary<string, Dictionary<string, PersistentItemData<T>>>();
public void OnAfterDeserialize()
{
// Convert itemData to dictionary for fast runtime access
scenes = new Dictionary<string, Dictionary<string, PersistentItemData<T>>>(serializedList.Count);
foreach (var serializableItem in serializedList)
{
scenes[serializableItem.SceneName][serializableItem.ID] = new PersistentItemData<T>
{
SceneName = serializableItem.SceneName,
ID = serializableItem.ID,
Value = serializableItem.Value
};
}
}
public void OnBeforeSerialize()
{
// Dictionaries can't be serialized so convert to list first
serializedList = new List<SerializableItemData>();
foreach (var scene in scenes)
{
foreach (var id in scene.Value)
{
serializedList.Add(new SerializableItemData
{
SceneName = scene.Key,
ID = id.Key,
Value = id.Value.Value
});
}
}
}
public void SetValue(PersistentItemData<T> itemData)
{
if (!scenes.ContainsKey(itemData.SceneName))
scenes[itemData.SceneName] = new Dictionary<string, PersistentItemData<T>>();
scenes[itemData.SceneName][itemData.ID] = itemData;
}
public bool TryGetValue(string sceneName, string id, out PersistentItemData<T> value)
{
if (scenes.ContainsKey(sceneName) && scenes[sceneName].ContainsKey(id))
{
value = scenes[sceneName][id];
return true;
}
else
{
value = default(PersistentItemData<T>);
return false;
}
}
}
When using JsonUtility to serialize SceneData the output is:
"sceneData":{"persistentBools":{},"persistentInts":{}}
I confirmed that there were 24 items in the list after the OnBeforeSerialize callback, so I’m not sure what is going wrong here.