Code: Select all
[SerializeField] private Dictionary<OverworldData, Dictionary<ObjectiveData, (bool hermit_0, bool hermit_1)>> _overworldDataObjectives = new();
My dictionary contains, for each OverworldData, whether each objective has been achieved or not by player 0 (hermit_0) and player 1.
Here, OverworldData and ObjectiveData are only used as references so that I know what has been achieved, I do not want to load and save these data.
When I try to do it with the type manager, when trying to load the file I get the following error
Code: Select all
ArgumentNullException: Value cannot be null.
Code: Select all
activeES3File.LoadInto(key, object);
Code: Select all
case "_overworldDataObjectives":
instance = (Objectives.ObjectivesProgressionData.ObjectivesProgressionData)reader.SetPrivateField("_overworldDataObjectives", reader.Read<System.Collections.Generic.Dictionary<Levels.Overworld.OverworldData, System.Collections.Generic.Dictionary<Objectives.ObjectiveData, System.ValueTuple<System.Boolean, System.Boolean>>>>(), instance);
break;
Sorry if my question is not clear, I'm happy to answer any questions!
Edit/addendum:
I tried to move the second dictionary to a separate class like this:
Code: Select all
[SerializeField] private Dictionary<OverworldData, ObjectivesStatus> _overworldDataObjectives = new();
[Serializable]
public class ObjectivesStatus
{
[SerializeField, OdinSerialize, ES3Serializable] private Dictionary<ObjectiveData, (bool hermit_0, bool hermit_1)> _objectivesStatusDictionary = new ();
}
The serialised data looks like this:
Code: Select all
"PlayerObjectiveProgression" : {
"__type" : "Objectives.ObjectivesProgressionData.ObjectivesProgressionData,Scripts.Objectives.ObjectivesProgressionData",
"value" : {
"__type" : "Objectives.ObjectivesProgressionData.ObjectivesProgressionData,Scripts.Objectives.ObjectivesProgressionData",
"_ES3Ref" : "-1",
"_overworldDataObjectives" : {{
"_ES3Ref" : "732210138513345046"
}:{
"_objectivesStatusDictionary" : {{
"__type" : "Objectives.ObjectiveData_KillNEnemiesInXSeconds,Scripts.Objectives.Objective_KillNEnemiesInXSeconds",
"_ES3Ref" : "4591167169304822108"
}:{
"Item1" : false,
"Item2" : false
},{
"__type" : "Objectives.ObjectiveData_FastDropXTimes,Scripts.Objectives.Objective_FastDropXTimes",
"_ES3Ref" : "7333472232547831490"
}:{
"Item1" : false,
"Item2" : false
},{
"__type" : "Objectives.ObjectiveData_KillEnemyWithinNSecondsOfProtecting,Scripts.Objectives.Objective_KillEnemyWithinNSecondsOfProtecting",
"_ES3Ref" : "1305161628479100296"
}:{
"Item1" : false,
"Item2" : false
}
}
},{
"_ES3Ref" : "3347054852542240662"
}:{
"_objectivesStatusDictionary" : {{
"__type" : "Objectives.ObjectiveData_HitEnemyOfYTypeWithShell,Scripts.Objectives.Objective_HitEnemyOfYTypeWithShell",
"_ES3Ref" : "4411937744220982857"
}:{
"Item1" : true,
"Item2" : false
},{
"__type" : "Objectives.ObjectiveData_CatchShell,Scripts.Objectives.Objective_CatchShell",
"_ES3Ref" : "7420484619292968720"
}:{
"Item1" : false,
"Item2" : false
},{
"__type" : "Objectives.ObjectiveData_HitEnemyOfYTypeWithShell,Scripts.Objectives.Objective_HitEnemyOfYTypeWithShell",
"_ES3Ref" : "9146293061190203534"
}:{
"Item1" : true,
"Item2" : false
}
}
}
},
"serializationData" : {
"SerializedFormat" : 2,
"SerializedBytes" : "",
"ReferencedUnityObjects" : [
{
"__type" : "Levels.Overworld.OverworldData,Scripts.Levels.OverworldData",
"_ES3Ref" : "732210138513345046"
},{
"__type" : "Objectives.ObjectiveData_KillNEnemiesInXSeconds,Scripts.Objectives.Objective_KillNEnemiesInXSeconds",
"_ES3Ref" : "4591167169304822108"
},{
"__type" : "Objectives.ObjectiveData_FastDropXTimes,Scripts.Objectives.Objective_FastDropXTimes",
"_ES3Ref" : "7333472232547831490"
},{
"__type" : "Objectives.ObjectiveData_KillEnemyWithinNSecondsOfProtecting,Scripts.Objectives.Objective_KillEnemyWithinNSecondsOfProtecting",
"_ES3Ref" : "1305161628479100296"
},{
"__type" : "Levels.Overworld.OverworldData,Scripts.Levels.OverworldData",
"_ES3Ref" : "3347054852542240662"
},{
"__type" : "Objectives.ObjectiveData_HitEnemyOfYTypeWithShell,Scripts.Objectives.Objective_HitEnemyOfYTypeWithShell",
"_ES3Ref" : "4411937744220982857"
},{
"__type" : "Objectives.ObjectiveData_CatchShell,Scripts.Objectives.Objective_CatchShell",
"_ES3Ref" : "7420484619292968720"
},{
"__type" : "Objectives.ObjectiveData_HitEnemyOfYTypeWithShell,Scripts.Objectives.Objective_HitEnemyOfYTypeWithShell",
"_ES3Ref" : "9146293061190203534"
}
],
"SerializedBytesString" : "",
"Prefab" : null,
"PrefabModificationsReferencedUnityObjects" : [
],
"PrefabModifications" : [
],
"SerializationNodes" : [
{
"Name" : "_overworldDataObjectives",
"Entry" : 7,
"Data" : "0|System.Collections.Generic.Dictionary`2[[Levels.Overworld.OverworldData, Scripts.Levels.OverworldData],[Objectives.ObjectivesProgressionData.ObjectivesStatus, Scripts.Objectives.ObjectivesProgressionData]], mscorlib"
},{
"Name" : "comparer",
"Entry" : 7,
"Data" : "1|System.Collections.Generic.ObjectEqualityComparer`1[[Levels.Overworld.OverworldData, Scripts.Levels.OverworldData]], mscorlib"
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 12,
"Data" : "2"
},{
"Name" : null,
"Entry" : 7,
"Data" : ""
},{
"Name" : "$k",
"Entry" : 10,
"Data" : "0"
},{
"Name" : "$v",
"Entry" : 7,
"Data" : "2|Objectives.ObjectivesProgressionData.ObjectivesStatus, Scripts.Objectives.ObjectivesProgressionData"
},{
"Name" : "_objectivesStatusDictionary",
"Entry" : 7,
"Data" : "3|System.Collections.Generic.Dictionary`2[[Objectives.ObjectiveData, Scripts.Objectives],[System.ValueTuple`2[[System.Boolean, mscorlib],[System.Boolean, mscorlib]], mscorlib]], mscorlib"
},{
"Name" : "comparer",
"Entry" : 7,
"Data" : "4|System.Collections.Generic.ObjectEqualityComparer`1[[Objectives.ObjectiveData, Scripts.Objectives]], mscorlib"
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 12,
"Data" : "3"
},{
"Name" : null,
"Entry" : 7,
"Data" : ""
},{
"Name" : "$k",
"Entry" : 10,
"Data" : "1"
},{
"Name" : "$v",
"Entry" : 7,
"Data" : "System.ValueTuple`2[[System.Boolean, mscorlib],[System.Boolean, mscorlib]], mscorlib"
},{
"Name" : "Item1",
"Entry" : 5,
"Data" : "false"
},{
"Name" : "Item2",
"Entry" : 5,
"Data" : "false"
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : null,
"Entry" : 7,
"Data" : ""
},{
"Name" : "$k",
"Entry" : 10,
"Data" : "2"
},{
"Name" : "$v",
"Entry" : 7,
"Data" : "System.ValueTuple`2[[System.Boolean, mscorlib],[System.Boolean, mscorlib]], mscorlib"
},{
"Name" : "Item1",
"Entry" : 5,
"Data" : "false"
},{
"Name" : "Item2",
"Entry" : 5,
"Data" : "false"
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : null,
"Entry" : 7,
"Data" : ""
},{
"Name" : "$k",
"Entry" : 10,
"Data" : "3"
},{
"Name" : "$v",
"Entry" : 7,
"Data" : "System.ValueTuple`2[[System.Boolean, mscorlib],[System.Boolean, mscorlib]], mscorlib"
},{
"Name" : "Item1",
"Entry" : 5,
"Data" : "false"
},{
"Name" : "Item2",
"Entry" : 5,
"Data" : "false"
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 13,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : null,
"Entry" : 7,
"Data" : ""
},{
"Name" : "$k",
"Entry" : 10,
"Data" : "4"
},{
"Name" : "$v",
"Entry" : 7,
"Data" : "5|Objectives.ObjectivesProgressionData.ObjectivesStatus, Scripts.Objectives.ObjectivesProgressionData"
},{
"Name" : "_objectivesStatusDictionary",
"Entry" : 7,
"Data" : "6|System.Collections.Generic.Dictionary`2[[Objectives.ObjectiveData, Scripts.Objectives],[System.ValueTuple`2[[System.Boolean, mscorlib],[System.Boolean, mscorlib]], mscorlib]], mscorlib"
},{
"Name" : "comparer",
"Entry" : 9,
"Data" : "4"
},{
"Name" : "",
"Entry" : 12,
"Data" : "3"
},{
"Name" : null,
"Entry" : 7,
"Data" : ""
},{
"Name" : "$k",
"Entry" : 10,
"Data" : "5"
},{
"Name" : "$v",
"Entry" : 7,
"Data" : "System.ValueTuple`2[[System.Boolean, mscorlib],[System.Boolean, mscorlib]], mscorlib"
},{
"Name" : "Item1",
"Entry" : 5,
"Data" : "true"
},{
"Name" : "Item2",
"Entry" : 5,
"Data" : "false"
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : null,
"Entry" : 7,
"Data" : ""
},{
"Name" : "$k",
"Entry" : 10,
"Data" : "6"
},{
"Name" : "$v",
"Entry" : 7,
"Data" : "System.ValueTuple`2[[System.Boolean, mscorlib],[System.Boolean, mscorlib]], mscorlib"
},{
"Name" : "Item1",
"Entry" : 5,
"Data" : "false"
},{
"Name" : "Item2",
"Entry" : 5,
"Data" : "false"
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : null,
"Entry" : 7,
"Data" : ""
},{
"Name" : "$k",
"Entry" : 10,
"Data" : "7"
},{
"Name" : "$v",
"Entry" : 7,
"Data" : "System.ValueTuple`2[[System.Boolean, mscorlib],[System.Boolean, mscorlib]], mscorlib"
},{
"Name" : "Item1",
"Entry" : 5,
"Data" : "true"
},{
"Name" : "Item2",
"Entry" : 5,
"Data" : "false"
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 13,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 13,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
}
]
}
}
},
Edit/addendum 2:
I tried to replace everything with lists, to see if the error would be with the dictionaries:
Code: Select all
[SerializeField, ES3Serializable] private List<(OverworldData overworldData, ObjectivesStatus objectivesStatus)> _overworldDataObjectives = new();
[Serializable]
public class ObjectivesStatus
{
[SerializeField, OdinSerialize, ES3Serializable]
private List<ObjectiveData> _objectivesHemit_0 = new List<ObjectiveData>();
[SerializeField, OdinSerialize, ES3Serializable]
private List<ObjectiveData> _objectivesHemit_1 = new List<ObjectiveData>();
}
But my serialised data is wrong, the referenses to the objects are lost, they are null. The serialised data:
Code: Select all
"PlayerObjectiveProgression" : {
"__type" : "Objectives.ObjectivesProgressionData.ObjectivesProgressionData,Scripts.Objectives.ObjectivesProgressionData",
"value" : {
"__type" : "Objectives.ObjectivesProgressionData.ObjectivesProgressionData,Scripts.Objectives.ObjectivesProgressionData",
"_ES3Ref" : "-1",
"_overworldDataObjectives" : [
{
"Item1" : null,
"Item2" : {
"_objectivesHemit_0" : [
null,null
],
"_objectivesHemit_1" : [
]
}
}
],
"serializationData" : {
"SerializedFormat" : 2,
"SerializedBytes" : "",
"ReferencedUnityObjects" : [
],
"SerializedBytesString" : "",
"Prefab" : null,
"PrefabModificationsReferencedUnityObjects" : [
],
"PrefabModifications" : [
],
"SerializationNodes" : [
{
"Name" : "_overworldDataObjectives",
"Entry" : 7,
"Data" : "0|System.Collections.Generic.List`1[[System.ValueTuple`2[[Levels.Overworld.OverworldData, Scripts.Levels.OverworldData],[Objectives.ObjectivesProgressionData.ObjectivesStatus, Scripts.Objectives.ObjectivesProgressionData]], mscorlib]], mscorlib"
},{
"Name" : "",
"Entry" : 12,
"Data" : "1"
},{
"Name" : null,
"Entry" : 7,
"Data" : "System.ValueTuple`2[[Levels.Overworld.OverworldData, Scripts.Levels.OverworldData],[Objectives.ObjectivesProgressionData.ObjectivesStatus, Scripts.Objectives.ObjectivesProgressionData]], mscorlib"
},{
"Name" : "Item1",
"Entry" : 6,
"Data" : ""
},{
"Name" : "Item2",
"Entry" : 7,
"Data" : "1|Objectives.ObjectivesProgressionData.ObjectivesStatus, Scripts.Objectives.ObjectivesProgressionData"
},{
"Name" : "_objectivesHemit_0",
"Entry" : 7,
"Data" : "2|System.Collections.Generic.List`1[[Objectives.ObjectiveData, Scripts.Objectives]], mscorlib"
},{
"Name" : "",
"Entry" : 12,
"Data" : "2"
},{
"Name" : null,
"Entry" : 6,
"Data" : ""
},{
"Name" : null,
"Entry" : 6,
"Data" : ""
},{
"Name" : "",
"Entry" : 13,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "_objectivesHemit_1",
"Entry" : 7,
"Data" : "3|System.Collections.Generic.List`1[[Objectives.ObjectiveData, Scripts.Objectives]], mscorlib"
},{
"Name" : "",
"Entry" : 12,
"Data" : "0"
},{
"Name" : "",
"Entry" : 13,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
},{
"Name" : "",
"Entry" : 13,
"Data" : ""
},{
"Name" : "",
"Entry" : 8,
"Data" : ""
}
]
}
}
},
Any ideas?
Edit/addendum 3:
I finally solved it by replacing the tuple with a class:
Code: Select all
[SerializeField, ES3Serializable] private List<OverworldObjectivesStatus> _overworldDataObjectives = new();
[SerializeField]
public class OverworldObjectivesStatus
{
[SerializeField, ES3Serializable] private OverworldData overworldData;
[SerializeField, ES3Serializable] private ObjectivesStatus objectivesStatus;
}
Or should I have declared that type somewhere?
Sorry if I missed something in the doc.
This approach seems quite a bit slower than my dictionaries approach, it works but if there is an option to go back to the dictionaries that would be fantastic.
Thanks a lot!
Edit/addendum 4:
Hmm no, still only works from time to time, and randomly sets all the fields to null. It does keep the structure though.