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?