Hi.
I have some questions about the implementation of the save system into my game. The documentation is very good so I have a grasp of how it works but I'm still not entirely sure about some stuff so I prefer asking you right away.
I want my game to automatically save after the loading of some levels, what is the best way to do that? I can smell a bug coming if it saves also every time those levels loads. Because since there is a 1 frame delay, every time the player will load this level, the save point will be 1 frame after. So maybe it needs to save the first time the level loads only. But perhaps I'm over complicating stuff.
I have a pause menu UI with a button to load the last checkpoint, should I put it in the Dialogue Manager Canvas, does it matter?
I will have a menu where the player can load the save they want, with the name of the level, the date and time in which the save happened, and a screenshot of the level. How could I get those data from the saves?
I have many scenes in my game and since the Dialogue Manager is a singleton: Should I put it only in the main menu scene and not in the other ones since it survives. Or should I put it everywhere but check on Awake if there is already a Dialogue Manager present and only enable it if there isn't?
ProvencalG wrote: ↑Wed Nov 25, 2020 8:37 am1. I want my game to automatically save after the loading of some levels, what is the best way to do that? I can smell a bug coming if it saves also every time those levels loads. Because since there is a 1 frame delay, every time the player will load this level, the save point will be 1 frame after. So maybe it needs to save the first time the level loads only. But perhaps I'm over complicating stuff.
I recommend adding a small script to the GameObject that has the SaveSystem component. This script should do two things:
1. Have a variable that you can set true when you want to save after loading a level.
2. Hook into the SaveSystem.saveDataApplied C# event and save the game if the variable is true. Example script
public class SaveAfterLoadingSomeLevels : MonoBehaviour
{
public static bool saveAfterLoadingLevel = false; // Set true to save after loading next level.
public int slotNumber = 1;
void OnEnable()
{
SaveSystem.saveDataApplied += OnSaveDataApplied;
}
void OnDisable()
{
SaveSystem.saveDataApplied -= OnSaveDataApplied;
}
void OnSaveDataApplied()
{
if (saveAfterLoadingLevel) SaveSystem.SaveToSlot(slotNumber);
saveAfterLoadingLevel = false;
}
}
ProvencalG wrote: ↑Wed Nov 25, 2020 8:37 am2. I have a pause menu UI with a button to load the last checkpoint, should I put it in the Dialogue Manager Canvas, does it matter?
It doesn't matter. It doesn't even need to directly reference the SaveSystem component. You can add a SaveSystemMethods component to the button and connect the button's OnClick() event to SaveSystemMethods.LoadFromSlot, or you can call SaveSystem.LoadFromSlot() in a C# script.
ProvencalG wrote: ↑Wed Nov 25, 2020 8:37 am3. I will have a menu where the player can load the save they want, with the name of the level, the date and time in which the save happened, and a screenshot of the level. How could I get those data from the saves?
Two ways:
Maintain an independent catalog of your saved games. Store the level name, date, time, and screenshot in the catalog.
Or write a custom saver component that stores this information in the saved game itself. The advantage is that you don't have to maintain a separate catalog. The disadvantage is that you have to read every saved game file to retrieve the info about all of the saves.
How to save meta info in saved games
To record meta info about the save, you can write a simple custom saver component. Here's an example:
public class TimeSaver : Saver
{
public override string RecordData()
{
return System.DateTime.Now.ToString(); // Current system time.
}
public override void ApplyData(string s) { /* No need to do anything in ApplyData */ }
}
(The Templates/Scripts folder has a starter template for saver classes.)
To show it in your load game menu, do something like:
var data = SaveSystem.storer.RetrieveSavedGameData(1); // Get data from slot 1.
TimeText.text = data.GetData("MyTimeSaverKey");
ProvencalG wrote: ↑Wed Nov 25, 2020 8:37 am4. I have many scenes in my game and since the Dialogue Manager is a singleton: Should I put it only in the main menu scene and not in the other ones since it survives. Or should I put it everywhere but check on Awake if there is already a Dialogue Manager present and only enable it if there isn't?
You can put it everywhere, and you don't have to do anything else. The Dialogue System will automatically remove extra instances of itself at runtime. This way you can easily test any scene in the Unity editor's play mode without having to arrive from the main menu scene.
I recommend adding a small script to the GameObject that has the SaveSystem component. This script should do two things:
1. Have a variable that you can set true when you want to save after loading a level.
2. Hook into the SaveSystem.saveDataApplied C# event and save the game if the variable is true.
Thanks for the quick answer, you are always really helpful!
I do not find the SaveSystem.saveDataApplied C# event
I searched in SaveSystem.cs, nothing about saveDataApplied.