I've been trying to understand how best to approach carrying state over between scenes, and how to save/load game state. I've built an isolated project to focus on building out this approach.
You can view the project on GitHub.
Essentially, my approach is to use a singleton StateCache
, which tracks all state objects, such as the PlayerState
in my example. When the PlayerMove
script (and therefore the player object) is destroyed (i.e. when a different scene is loaded), it writes its latest state to the StateCache
. When clicking the Save button, all state in the cache is written to a JSON file. Finally, when loading the game data, the JSON is parsed into appropriate state types and the StateCache
is prepopulated with this data.
Some caveats here, though, that make this more complex:
- To be able to load the state using strong typing, I need to write the actual state object type names into the JSON object.
- When loading, I load the next scene first and then prepopulate the cache. However, the player reads its state when the scene is loaded (before the cache is populated). If I load the cache before the scene is loaded, then in the example, the player will be destroyed and overwrite the loaded data in the cache (this could be mitigated by loading from a main menu scene where no player exists).
- Due to #2, I need to run an additional step to find all active instances that have a state, and apply the state from the cache (if it exists).
- Also, not necessarily a caveat, but adds complexity, I've brought in Zenject for dependency injection to get away from having static instance references.
To try to explain it visually, I've also created this diagram:
This is working in my isolated project. But it feels overly complicated for what seems like a common problem. I'm relatively new to Unity, building a game as a casual hobby, so I'm keen to understand recommended approaches here. Is there a better way? Or is this complexity necessary?
PlayerPrefs
as it appears the recommendation is to use these for customization and options (brightness, volume level, etc). It also writes the data out in a format that can be modified (my read/write to save file approach can be extended with an encrypted binary output, if I want). I'm fairly new to the use of scriptable objects, though, so I'd be interested to understand how you would approach state caching (between scenes) and read/writing save data with them \$\endgroup\$PlayerPrefs
is intended for saving preferences such as volume settings (hence the name), not complex game state. It's not suitable for Samuel's needs. \$\endgroup\$