πŸ’ΎSave System

Core system for player data save & load

How it's work

namespace Game.Core;

Save system is powered with BinaryFormatter and NewtonsoftJson, that serialize and desialize data.

You can find SaveBinarySerializer.cs in: Assets_Main\Scripts\Common\SaveSystem\Serializers

Also you can implement your own serializer with ISaveSerializer.cs interface. To change serializer -> set it in SaveSystem.cs code (field saveSerializer)

  • You can access SaveSystem any way in code and take data by Data property. Data is SaveData class that holds all neccessary data that should be stored between game sessions.

  • You can delete save by different ways:

1. pressing 'Delete' key on keyboard while running the game in editor; 2. manualy delete file in AppData\LocalLow\Company_Name\Game_Name\gameData.sqw. FileName by default is gameData.sqw, but you can change it in SaveSystem.cs in FileName readonly string value.

    /// <summary>
    /// Save data file name in <see cref="Application.persistentDataPath"/>
    /// </summary>
    private readonly string FileName = "gameData.sqw";

3. from Inspector menu on SaveSystem object script:

Save and Delete btns in inspector (select SaveSystem obj)
  • Here is how default SaveData class looks (separate SaveData.cs file):

[System.Serializable]
public class SaveData {
    /// <summary>
    /// version check here <see cref="VersionValidator"/>
    /// </summary>
    public string GameVersion;

    /// <summary>
    /// Users currency, to manipulate use <see cref="CashManager"/> API
    /// Start values in Currency Settings config
    /// </summary>
    public Dictionary<Currencies, float> Currencies = null;

    public Languages Language = Languages.English;

#if UNITY_EDITOR
    public void LogAdditionalData() {
        System.Text.StringBuilder info = new System.Text.StringBuilder("Save additional data: \n");

        info.Append(Newtonsoft.Json.JsonConvert.SerializeObject(Currencies) + "\n");

        UnityEngine.Debug.Log(info.ToString());
    }
#endif
}

How to Serialize custom classes

[System.Serializable] //must be
public class PlayerData {
    // default player Level, 
    // if user lanch game first time then what we wrote here
    // will be as default
    public int Level = 1;
    
    // you can pre-init data structures for save access
    public List<WeaponData> Weapons = new List<WeaponData>();
    
    public SerializableVector3 Position; // Vector3 is not serializable
    public SerializableQuaternion Rotation; // so use Serializable_Type_ 
                             // Serializable_Type_ is custom implemented struct
}

[System.Serializable] //must be
public class WeaponData {
    public WeaponType Type;
    public int BulletsAmount;
    public string CustomName;
    ..
}

[System.Serializable] //must be
public enum WeaponType {
    Melee,
    Pistol
    ..
}

And in SaveData it will be like this:

[System.Serializable]
public class SaveData {
    // here add your custom class
    public PlayerData PlayerData;
}

Now you need to access it and change it. Saves on iOS/Android will be automaticaly so after game restart you will remain PlayerData info in SaveData.

Access Data in code

You can access SaveSystem.Instance.Data in Awake() unity function, because of script execution order in ProjectSettings. And it will looks like this:

public void Awake() {
    int currencies = SaveSystem.Instance.Data.Currencies;
    
    // or you can do it like this (if you need to access Data multiple times)
    var saveData = SaveSystem.Instance.Data;
    var currencies = saveData.Currencies;
    var playerData = saveData.PlayerData;
    
    // set new data
    SaveSystem.Instance.Data.PlayerData.Position = transform.position;
}

More examples you can find in Assets/_Main/_Examples/Save System.

Last updated