LoadInto Erasing Nested Value Type
Posted: Wed May 05, 2021 5:20 pm
Hi,
I am using Easy Save 3 to handle the saving and loading of ScriptableObject assets. I am running into a bug where loading a ScriptableObject through LoadInto erases the values of a list of a nested value type that has a custom ES3 Type script defined for it.
The main ScriptableObject is named "LevelData", and I have configured a custom ES3 Type Script to save the fields of level data that I would like to have saved. Here is the read method below:
Inside of the LevelData class, I have defined a subclass called LevelScoreGoal:
LevelScoreGoal has a custom ES3 Type Script as well, since the only thing that needs to be saved is the field State. Here is the custom read function for LevelScoreGoal:
Saving works fine, and a saved LevelData looks like this:
The problem arises when I try to load a saved LevelData during runtime. I use LoadInto<LevelData> because I already have a reference to the ScriptableObject asset in the project. The loading works correctly (including for non-saved fields) until it loads the list of LevelScoreGoals called "ScoreGoalsAndLinks". It ends up erasing all of the fields inside the LevelScoreGoals within that list except the one I have told ES3 to save, the State field.
Given that LoadInto loads the non-saving fields correctly in the outer LevelData class, it is confusing to me that an inner class would have its fields erased except for the one that is marked to save. Is it possible to get Easy Save to load into the ScoreGoalsAndLinks correctly without needing to save every field in every LevelScoreGoal, or make LevelScoreGoal a reference type (which doesn't make sense for my setup).
Thanks for your help!
Gabriel
I am using Easy Save 3 to handle the saving and loading of ScriptableObject assets. I am running into a bug where loading a ScriptableObject through LoadInto erases the values of a list of a nested value type that has a custom ES3 Type script defined for it.
The main ScriptableObject is named "LevelData", and I have configured a custom ES3 Type Script to save the fields of level data that I would like to have saved. Here is the read method below:
Code: Select all
protected override void ReadScriptableObject<T>(ES3Reader reader, object obj)
{
var instance = (LevelData)obj;
foreach(string propertyName in reader.Properties)
{
switch(propertyName)
{
case "Unlocked":
instance.Unlocked = reader.Read<System.Boolean>(ES3Type_bool.Instance);
break;
case "HighScore":
instance.HighScore = reader.Read<System.Int32>(ES3Type_int.Instance);
break;
case "CoOpHighScore":
instance.CoOpHighScore = reader.Read<System.Int32>(ES3Type_int.Instance);
break;
case "ScoreGoalsAndLinks":
instance.ScoreGoalsAndLinks = reader.Read<System.Collections.Generic.List<LevelData.LevelScoreGoal>>();
break;
case "_DEBUG_SAVE_FLAG":
instance._DEBUG_SAVE_FLAG = reader.Read<System.Boolean>(ES3Type_bool.Instance);
break;
default:
reader.Skip();
break;
}
}
}
Code: Select all
[System.Serializable]
public class LevelScoreGoal
{
public int ScoreGoalOnePlayer;
public int ScoreGoalTwoPlayer;
public int NumberOfLinks;
public string UnlockKey;
public LinkState State;
public enum LinkState
{
Locked,
Revealing,
Unlocked
}
...
Code: Select all
protected override void ReadObject<T>(ES3Reader reader, object obj)
{
var instance = (LevelData.LevelScoreGoal)obj;
foreach(string propertyName in reader.Properties)
{
switch(propertyName)
{
case "State":
instance.State = reader.Read<LevelData.LevelScoreGoal.LinkState>();
break;
default:
reader.Skip();
break;
}
}
}
Code: Select all
"Level_Data_Level2Demo" : {
"__type" : "LevelData,Assembly-CSharp",
"value" : {
"_ES3Ref" : "5353275289805580540",
"_ES3Ref" : "5353275289805580540",
"Unlocked" : false,
"HighScore" : 0,
"CoOpHighScore" : 0,
"ScoreGoalsAndLinks" : [
{
"State" : 0
},{
"State" : 0
},{
"State" : 0
}
],
"_DEBUG_SAVE_FLAG" : false
}
},
Given that LoadInto loads the non-saving fields correctly in the outer LevelData class, it is confusing to me that an inner class would have its fields erased except for the one that is marked to save. Is it possible to get Easy Save to load into the ScoreGoalsAndLinks correctly without needing to save every field in every LevelScoreGoal, or make LevelScoreGoal a reference type (which doesn't make sense for my setup).
Thanks for your help!
Gabriel