Maintaining ES3References between scenes, singletons, serializing prefabs and scriptable objects

Discussion and help for Easy Save 3
Post Reply
steve18624
Posts: 5
Joined: Tue Jul 28, 2020 1:58 am

Maintaining ES3References between scenes, singletons, serializing prefabs and scriptable objects

Post by steve18624 »

I am posting this because I couldn’t find the answers in other posts and hopefully it will help other people with similar questions. I am running into a few issues when trying to use ES3 in a more complex project (e.g. more than one scene and where objects that need to be saved/serialized are instantiated/spawned by a spawner script and not in the scene hierarchy before play/build).

#1 Persisting ES3ReferenceManager and related references between scenes
I need to persist the values of Scriptable Objects (SO) or other data classes between scenes (e.g. start at character creation scene, create the character, and use the character created or modified in the next scene). This seems to cause problems for ES3 when the SO’s have properties that reference prefabs or other SOs.

Since ES3 generates new references for all items in the reference manager in each scene, it doesn’t appear that ES3 handles multi scene persistence by default. I’ve had limited success using ES3ReferenceMgr.Current.ChangeId(); to create a non-randomly generated reference. For this to work, I needed to:

1) Attach another script that was a singleton with a DoNotDestroy selected to the gameobject that had ES3ReferenceManager in the starting scene. This allows the ES3RefManager to persist scenes and maintain the correct references. However, for this to work I had to:
2) Drop every SO that I wanted to persist (i.e. save) into a list in a Save class in the first/starting scene. This allowed the ES3RefManager to establish a reference (i.e. unique ID) for the SOs. This unique ID was then maintained into the next scene because the ES3ReferenceManager was not destroyed (losing all of it’s references to the SOs) and reinstantiated in the next scene, which appears to be the default behaviour.

#2 ES3ReferenceMgr.Current.Merge();
Anyone know why this exists and how it should this be used? There is no documentation about it. I would assume that it merges ES3ReferenceMgrs between scenes but as mentioned earlier, ES3ReferenceMgr’s don’t persist scenes by default unless attached to a Singleton.

#3 Serializing prefabs and scriptable objects
This doesn’t appear to work for objects instantiated via scripts (i.e. that do not exist in the scene hierarchy before build/play).

In general, I haven’t got ES3 to work correctly with:
1) Nested Scriptable Objects (i.e. a SO with property that references another SO)
2) SOs that have properties that reference a Prefab

In both cases, upon save and then subsequent load, the values in the inspector for these fields are cleared (i.e. set to null or say TypeMismatch).

An example of this is an object spawned by a Spawner that has properties that you want to serialize. For example, let’s say you have different characters that you’ve created using a CharacterData SO. Each character has a different 3D model prefab that is a property of your CharacterData SO and assigned in the inspector. You want to spawn/instantiate the characters via script into a scene and have them move around, then save their new position as well as the 3D model that they were at the time of save. I think the solution is to build a custom mapping/dictionary to the prefabs and other SOs or trying to hack something together using ES3 with the solution in I mentioned in #1. ES3 does not solve this problem natively.
User avatar
Joel
Moodkie Staff
Posts: 4846
Joined: Wed Nov 07, 2012 10:32 pm

Re: Maintaining ES3References between scenes, singletons, serializing prefabs and scriptable objects

Post by Joel »

Hi Steve,

I will try to answer your questions in order:
  1. Easy Save doesn't generate new references for all items in the scene. It will only generate new reference IDs for objects which don't exist in the scene prior to runtime, and are not loaded from an Easy Save file. This is because when you create an object at runtime, this will be a new reference of that object. That means the same reference won't exist between runs.
  2. As ES3ReferenceMgr.Current.Merge() is not documented and is only used internally, I strongly advise against using it. Easy Save automatically handles merging of managers when there are multiple managers in the same scene.
  3. The answer for this is the same as number one. In most cases the easiest solution is to use ES3ReferenceMgr.Current.Add(instance, id) to assign your own ID to the new object, ensuring that you use the same ID each time for that instance.
All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Post Reply