I use a BinaryFormatter to save a bunch of information about my player into a file, then load it again later. I’ve been doing this with no problem for a while, but I just tackled a new system and it seems to not be working, and I can’t figure out why.
I have this PlayerData class, and it stores information (relevantly, it stores the Name as a string, and it stores a Dictionary of SkillLevelData. The dictionary uses a GUID for each skill as the key, and the value it stores is a struct called SkillLevelData which has very simple data - the guid, the level of the skill.)
Because unity can’t serialize a dictionary, I use ISerializationCallbackReceiver to store the dictionary as two Lists.
This seems like a simple implementation, but for some reason, in OnAfterDeserialize, all of the data seems to be completely blank. I know that it does successfully serialize and deserialize, because my code later references other saved data - like the Name, particularly. But if I ask the code to print the Player’s Name during OnAfterDeserialize, it comes up as null. What’s going on? And more importantly, how do I fix it?
[System.Serializable]
public class EntityData : ISerializationCallbackReceiver
{
public string Name;
[SerializeField] private List<SkillLevelData> _skillLevelData = new List<SkillLevelData>();
public virtual void OnBeforeSerialize()
{
_skillLevelData.Clear();
if (SkillLevels is not null)
foreach (var kvp in SkillLevels)
{
//Debug.Log($"Saving into list: {kvp.Key} - {kvp.Value.RawLevel}");
_skillLevelData.Add(kvp.Value);
}
}
public virtual void OnAfterDeserialize()
{
SkillLevels = new Dictionary<string, SkillLevelData>();
foreach (var data in _skillLevelData)
{
Debug.Log($"Trying to deserialize skill data: {data.GUID} - {data.RawLevel}");
SkillLevels.TryAdd(data.GUID, data);
}
Debug.Log($"Entity {Name} deserializing. Size of _skillLevelData: {_skillLevelData.Count}");
}
Code has been simplified to remove unnecessary details. This is what SkillLevelData looks like.
[System.Serializable]
public struct SkillLevelData
{
public string GUID;
public CappedValue RawLevel;
public bool IsNull => string.IsNullOrEmpty(GUID);
public SkillLevelData(string guid, float level)
{
RawLevel = new CappedValue(level, 1000);
GUID = guid;
}
}
CappedValue is a class that just contains a float for a value and a float for its limit, then handles making sure it doesn’t go over that limit. It is also marked as Serializable.
Any help at all would be greatly appreciated. Thanks for reading.