Savegame - SebastianKErben/SKE.Unity3D GitHub Wiki
The Savegame namespace provides classes to help with the creation and management of SaveData. The first thing to do is to create a data class derived from the abstract SaveData class. The values you want to store in your SaveData need to be serializable by Unity3D's JsonUtility class. This means you can use public fields of basic types like int, float, byte, bool and string as well as arrays of those types and classes derived from Unity3D's MonoBehaviour and ScriptableObject. Any other functionality you want needs to be emulated by creating your own Serializable classes; an example would be to emulate a Dictionary composed of string keys and int values by creating a Serializable class that has two public fields (one string and one int field), then having an array of objects from this class in your SaveData class and writing methods to convert this array to a dictionary and vice versa.
A simple example would be
public class MyCoolSave : SaveData {
public string playerName;
public int lifes;
public int level;
public int score;
}
The next thing you will need is a class implementing the ISaveDataAccess interface. This will be used to provide Loading and Saving functionality for the SaveSystem. An implementation for file access can be found in the sub namespace Utils but for other means like cloud saving on different platforms the developer will have to write a dedicated class.
SaveSystem is a class derived from SingletonEternal and needs to be set up at the start of the game. The first thing to do is to set the SaveSystem's DataAccess. This needs to be an implementation of ISaveDataAccess; using the file access implementation from the Utils sub namespace the example would look like this:
SaveSystem.Instance.DataAccess = new Utils.SaveFile();
The next thing is to try and load an existing save. In the following example the save that shall be loaded is the auto save, but you can use your own identifiers when saving manually. If the save exists and has been loaded, we want to get it as a MyCoolSave object; if not, we need to create a new instance of the object:
MyCoolSave mySaveData;
if (SaveSystem.Instance.Load<MyCoolSave>("auto"))
mySaveData = SaveSystem.GetLoadedSave<MyCoolSave> ();
else
mySaveData = new MyCoolSave ();
SaveSystem.Instance.CurrentSaveData = mySaveData;
The reason for doing it this way is because the SaveSystem only knows the members from the abstract SaveData class and not what values we might have in our MyCoolSave class. For that reason, we're using the generic GetLoadedSave method and tell it that we expect a MyCoolSave object. We then "inject" mySaveData back into the SaveSystem, because GetLoadedSave will return a different object than what's already loaded in the SaveSystem. That's important because without doing that all data manipulation would not end up in the SaveSystem.
This is important! You probably want to handle the SaveData in either a static class or a Singleton so that you only have to do the loading once and and can then work on the SaveData reference all the time without needing to refresh the SaveSystem.
If you want, you can tell the SaveSystem to automatically save the data:
SaveSystem.Instance.AutoSave = true;
When set to true, the SaveSystem will always save the current SaveData on scene switches, change of application focus or pause and on application quit.
You can always save the data manually though by calling
Save(saveId);
An example can be found in Examples/Savegame and unit tests can be found in Editor/Tests/Savegame.