Loading Dictionary of Dictionary with scriptable objects

Discussion and help for Easy Save 3
Post Reply
Giezi
Posts: 8
Joined: Thu May 06, 2021 10:54 am

Loading Dictionary of Dictionary with scriptable objects

Post by Giezi »

I have a dictionary of dictionary that looks like this:

Code: Select all

[SerializeField] private Dictionary<OverworldData, Dictionary<ObjectiveData, (bool hermit_0, bool hermit_1)>> _overworldDataObjectives = new();
OverworldData is a serialised object that contains 3 Objectives, which each are expressed in a seriealised object.

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.
the error appears on this line, so when the object is being loaded into the reference object:

Code: Select all

activeES3File.LoadInto(key, object);
The error is when the custom type is trying to be loaded:

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;
My logic works inside Unity, but I'm guessing there might be a way smarter way to have references instead of what I'm doing?

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 same error occurs, but this time in ES3UserType_ObjectivesStatus, so seems that the issue is wit the <ObjectiveData, tuple> dictionary.

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>();
}
I don't get the previous error anymore, so I think there might have been an issue with a dictionary inside a serialised object?

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" : ""
			}
		]
	}
}
},
after loading, the reference is null in the inspector (makes sense, it's null in the 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;
}
So it looks like neither Dictionaries nor list of tules are supported in Scriptable Objects?

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.
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Loading Dictionary of Dictionary with scriptable objects

Post by Joel »

Hi there,

Judging by your call activeES3File.LoadInto(key, object) it sounds like you're using the ES3File API which has been depreciated for quite a long time. Instead you should be using caching: https://docs.moodkie.com/easy-save-3/es ... rformance/

You should also double-check that you're on the latest version of Easy Save.

If this doesn't resolve your issue please could you replicate this in a simple scene with a basic script and send me a link to it on moodkie.com/contact along with your order or invoice number and step-by-step instructions so I can see what is happening.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Giezi
Posts: 8
Joined: Thu May 06, 2021 10:54 am

Re: Loading Dictionary of Dictionary with scriptable objects

Post by Giezi »

Hy there!

Thanks for the fast answer :)

I am on the last version of the asset store, I updated the package last week (3.5.6)

You are right, I did load and save with the ES3File API.
With my dictionary routine, I now modified it to follow this logic, let me know if that makes sense:

Code: Select all

[SerializeField] private ES3Defaults es3Defaults;

es3Defaults.settings.location = ES3.Location.Cache;

string filepath = "myFile.sav";

ES3.CacheFile(filepath);
ES3Settings settings = new ES3Settings(filepath, es3Defaults.settings);

ES3.LoadInto("mykey", myScriptableObject, settings);
But I still get the same error:

Code: Select all

ArgumentNullException: Value cannot be null.
Parameter name: key
System.Collections.Generic.Dictionary`2[TKey,TValue].System.Collections.IDictionary.Add (System.Object key, System.Object value) (at <fd2d3e9b010a4ba4b3fdc0456cd6b40b>:0)
ES3Types.ES3DictionaryType.Read (ES3Reader reader) (at Assets/Plugins/Easy Save 3/Scripts/Types/Collection Types/ES3DictionaryType.cs:101)
ES3Reader.Read[T] (ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:280)
ES3Reader.Read[T] () (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:126)
ES3Types.ES3UserType_ObjectivesProgressionData.ReadScriptableObject[T] (ES3Reader reader, System.Object obj) (at Assets/Easy Save 3/Types/ES3UserType_ObjectivesProgressionData.cs:32)
ES3Types.ES3ScriptableObjectType.ReadUnityObject[T] (ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ScriptableObjectType.cs:31)
ES3Types.ES3UnityObjectType.ReadObject[T] (ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3UnityObjectType.cs:64)
ES3Types.ES3ObjectType.ReadInto[T] (ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:75)
ES3Types.ES3ObjectType.ReadInto[T] (ES3Reader reader, System.Object obj) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3ObjectType.cs:66)
ES3Reader.ReadObject[T] (System.Object obj, ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:243)
ES3Reader.ReadInto[T] (System.Object obj, ES3Types.ES3Type type) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:296)
ES3.DeserializeInto[T] (ES3Types.ES3Type type, System.Byte[] bytes, T obj, ES3Settings settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:897)
ES3.DeserializeInto[T] (System.Byte[] bytes, T obj, ES3Settings settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:887)
ES3File.LoadInto[T] (System.String key, T obj) (at Assets/Plugins/Easy Save 3/Scripts/ES3File.cs:277)
ES3.LoadInto[T] (System.String key, T obj, ES3Settings settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:591)
myScriptableObject is the scriptable object containing my dictionary:

Code: Select all

[SerializeField] private Dictionary<OverworldData, ObjectivesStatus> _overworldDataObjectives = new();
FYI I think I managed to get the code without dictionaries to work, it's just the dictionary inside the scriptable object that does not want to work.

Thanks a lot!

Edit:
I'm on a bit of a time crunch and this is part of a larger project, but as soon as I have more time I will extract the relevant parts and send you a project via pm.
Thanks!
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Loading Dictionary of Dictionary with scriptable objects

Post by Joel »

Hi there,

You shouldn't be using the ES3Defaults class and we've never documented or made this API public. Your use of settings is very convoluted and a bit redundant as you could just do this:

Code: Select all

ES3.CacheFile(filepath);
ES3.LoadInto("mykey", myScriptableObject, filePath, new ES3Settings(ES3.Location.Cache));
I strongly recommend only using Easy Save as documented as if we make changes internally this could easily break your code, and some of the internal code you're using doesn't work quite as you expect.

Also when you get a chance to put a sample project together please can you send it via Moodkie.com/contact as requested as this will create a support ticket so that we can book a slot to look at your project :)

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Giezi
Posts: 8
Joined: Thu May 06, 2021 10:54 am

Re: Loading Dictionary of Dictionary with scriptable objects

Post by Giezi »

Fair enough.

I did modify my save routine to follow that idea, but I still have the same error.

Also I tried to implement the same trick that worked earlier, save a list of objects rather than a dictionary for a new scriptable object I have, but this time it fails, all the references are -1:

Code: Select all

"_skills" : [
{
	"_skillSeries" : {
		"_ES3Ref" : "-1"
	},
	"_skillLevel" : 0
},{
	"_skillSeries" : {
		"_ES3Ref" : "-1"
	},
	"_skillLevel" : 0
}
],
here _skills is the list of objects and _skillSeries is a scritpableObject.

From reading the doc, I understand that "_ES3Ref" : "-1" should mean ES3 doesn't have a references to the object, e.g. if the object is not in the references, or if it is a temporary object.

But here it's a scriptable object. I also explicitly made sure to select the SOs and add them to the reference manually like described in the doc.

I am quite confused as to why this happens.

Sorry, hope this can be figured out.
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Loading Dictionary of Dictionary with scriptable objects

Post by Joel »

Hi there,

If the ScriptableObject is generated at runtime or Unity has made a copy of it, it won't be in the reference manager unless that ScriptableObject has been saved or loaded, which is why it will be -1. However, it's difficult to know exactly what is happening without a new project with a simple scene for me to be able to replicate it as described above.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Giezi
Posts: 8
Joined: Thu May 06, 2021 10:54 am

Re: Loading Dictionary of Dictionary with scriptable objects

Post by Giezi »

Yeah that's what I understood, but that's not the case.

All the SOs are in the project, I have another SO acting as library referencing them, and that library is referenced in the scene. And as mentioned I did add them manually as well with the right click method.

I found a workaround for it without using the SO so I'm good for now.

The deadline for the project is in 1.5 weeks (participating in steam remote play together), looks like I'm managing to save everything I need with the workarounds for now, but I will get back to you as soon as I'm done.

I've been using ES3 in this project for 2 years and been super happy, don't know why these 2 new classes have been so painful.

Thanks a lot for your time!
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Loading Dictionary of Dictionary with scriptable objects

Post by Joel »

Hi there,

Unfortunately as we have no other users experiencing this behaviour I would need to see a basic project which replicates it to be able to comment.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Post Reply