UPDATE #1: I'll be d*mned. I just had to add the scriptable objects to the ES3GlobalReferences, there are many references in there, including other scriptable objects like Post processing volumes and others, just not these one. Does it mean that for every new scriptable object that I create I'll have to add it there manually?
UPDATE #2: I'll just continue working and testing to see what's up, suddenly it's now working, after tinkering with the setting's use Global References file back and forth, even if it currently shows no references, it is still working. So I'll need to come up with better repro steps and see if it is actually an issue. The error was that the 'key' of the scriptable object to use for the dictionary was null.
-------------------------------
Hello! Just wanted to add to the discussion as this seem to be the exact issue I'm having.
I'm by no means a persistence expert and this is the first-time/first-day ever trying this actually, enter Easy Save 3, which already gives me a 'save file' ready to use in just under an hour of playing around.
But on the scriptable objects front, it is not quite clear how to go about static nested references on them, let me explain the use case as best as I can:
0. It's a sort of flappy bird, each run the player accumulates kills, tricks, dodges, etc. When the player dies it's all reset (by hand because SOs between plays).
1. There's a PlayerRuntimeData scriptable object that contains a set of config values and the current session's running stats (how many jumps, tricks, objects evaded, etc have happened in the currently running session) -> done like this so that other objects (like UI elements) can reference the same SO, effectively having a middle man link between them and the data.
2.
The problematic part: every time the player collects/kills/jumps something and want to calculate the score, I don't add it to a running score directly, instead I add an
scriptable object that represents the object collected (that SO has extra data that how much each item scores, colors and others) and how many have been collected so far
of that scriptable object in a dictionary, i.e. Dictionary<ColletableDataSo, int>.
Sumary explanation: there's a
PlayerRuntimeData ScriptableObject (which I Save and LoadInto<> manually) and inside there's a Dictionary at some point Dict<CollectableSoAsKey, howManyOfThatCollected_Int>. Could think of it as a glorified enum with a lot of data and flexible values (to create a new 'enum' just create new SOs of the same type and name it differently).
A few images might help:
The PlayerRuntimeData scriptable object (notice the dictionary I'm referring to)
- PlayerRuntimeData.png (270.32 KiB) Viewed 2310 times
And how Easy Save is serializing it (don't mind for now the actual value, these different run timestamps and couldn't catch it at the exact same time so the 'amount' doesn't match but the type does)
- PlayerRuntimeData_json.png (102.23 KiB) Viewed 2310 times
Reading through the forums it has come to my understanding that actually Unity creates a new instance of that SO every single time we hit play (and effectively ES3 shows this because every time I hit save it has a different _ES3Ref number assigned to it) and somehow makes sure that everybody that's referencing it gets the same one (please correct me if I'm wrong, that's what I understand by, paraphrasing, 'a new instance is created always').
Also read that dropping the reference on the reference manager will achieve that consistency but I couldn't find where this is exactly, the only reference link I have found so far was by adding an ES 3 Save Manager but it has 4K+ elements array in it and it recommends not expanding that list, I drop SOs there?
The other thing I tried was using ES3Settings member References by Ref and Value -> this at least allows it to load but it creates a truly freshly new instance of the scriptable object and not the reference used by the unity scenes drag'n'dropped on the inspectors, can continue developing like that, however the idea is to be able to adapt in the future the scores of players in the assets themselves and not bake it into the save file, at least for now.
This is how a collectable scriptable object looks like
There's bad guys, coin, rare coin, missiles, etc with their own scores and color values (and allows to expanded later on)
- CollectableDataScriptableObjectExample.png (116.31 KiB) Viewed 2310 times
So, ways to get around this:
- Maybe with a custom ES3 Type Reader?
- or if I could somehow get all scriptable object in a single list and store the index on that list instead?
- Also have to experiment with prefab references, I'm assuming prefabs are serializing fine, so could somehow use prefabs as SO holders? far from ideal but I'll take whatever works and expand later on.
I'm afraid I'm doing something horribly wrong though.
Thanks a lot in advance.