Page 1 of 1

Save System: Init scene when not loading a save game

Posted: Thu Oct 07, 2021 2:55 am
by NotVeryProfessional
I'm doing a bunch of setup things in my main scene controller, some of which I want to not run or run differently when I'm loading a save game.

I know I can hook into saveDataApplied to wait until all savers are done.

But how do I figure out in Start() whether or not I'm loading a save game and should wait for it?


If that wasn't clear, here's a simplified example:

In Start() I populate a list of characters in the scene. These are stored in the save game because they can change during gameplay. But when I am entering the scene not from a save game, there's a default list I want to initialize (procedural generation). Obviously, it would be nonsense to run the generation, then receive the saveDataApplied event, throw it away and use the saved list. I'd like to essentially say "if I'm loading a game and waiting for the saver to run, skip this procedural generation part, we anyway won't need it".

Is there a "load game in progress" flag or something?

Re: Save System: Init scene when not loading a save game

Posted: Thu Oct 07, 2021 8:51 am
by Tony Li
Hi,

The SaveSystem class has a bunch of events you can hook into. You can hook into loadStarted and saveDataApplied to know if you're loading a save game. If you're between loadStarted and saveDataApplied, you're loading a save game.

Here are the order of events:
  • SaveSystem.loadStarted: Called at the start of loading a save game. If something is assigned to this event, the event is called, and then the save system waits 1 frame before actually loading the scene in case your event handler needs a frame to set up.
  • SaveSystem.sceneLoaded: Called whenever the save system has just finished loading a scene, whether it's loading a save game or just changing scenes.
  • SaveSystem.loadEnded: Called right after SaveSystem.sceneLoaded, but only if loading a save game. (Note: The whole load game process isn't done yet; see the next event below.)
  • SaveSystem.saveDataApplied: If loading a save game, after the number of frames specified by the Save System component's Frames To Wait Before Apply Data, the save system tells savers to apply their save data. Then it calls this event.

Re: Save System: Init scene when not loading a save game

Posted: Thu Oct 07, 2021 10:18 am
by NotVeryProfessional
I don't think that'd work for me.

I'm loading the game in a main menu scene. The setup code then is on a levelcontroller object that lives in the scene that is loaded. So by the time it's there, the loadStarted event has already fired.

I guess I'll be making a workaround where I store my own "loading a savegame" flag in some global object.

Re: Save System: Init scene when not loading a save game

Posted: Thu Oct 07, 2021 10:49 am
by Tony Li
You could define a static variable/property (or some other way of holding global data) in your levelcontroller script. Example:

Code: Select all

public static bool IsLoadingSaveGame { get; set; } = false;
In your main menu scene's script, set it true:

Code: Select all

void Awake() { SaveSystem.loadStarted += OnLoadStarted; }
void OnDestroy() { SaveSystem.loadStarted -= OnLoadStarted; }
void OnLoadStarted() { levelcontroller.IsLoadingSaveGame = true; }
And in levelcontroller, check the property:

Code: Select all

void Start()
{ // (Assumes Frames To Wait Before Apply Data is 1+)
    if (IsLoadingSaveGame) SaveSystem.saveDataApplied += OnSaveDataApplied;
    else DoProceduralGeneration();
}
void OnSaveDataApplied()
{
    SaveSystem.saveDataApplied -= OnSaveDataApplied;
    IsLoadingSaveGame = false;
}