Infinite Save Scripting
Scripting an infinite save system.
Step 1: Create a Script
Create a script or multiple scripts that will handle all save menu functionality.
For this example, we will create a single script called InfiniteSavesExample.cs
.
Start the script by adding the member variables that can be set from the inspector.
public class InfiniteSavesExample : MonoBehaviour
{
[SerializeField]
private Button saveSlotPrefab;
[SerializeField]
private Button saveSlotCreator;
[SerializeField]
private Transform content;
[SerializeField]
private Text timeElapsedText;
[SerializeField]
private Toggle modeToggle;
}
Remember to add a GameObject to the scene and add this script to it. At this point, we should have everything to populate the inspector properties.

Properties
Save Slot Prefab: the save slot button prefab.
Save Slot Creator: the button that will create a new save.
Content: the scroll view's content object.
Time Elapsed Text: the text object that will display the time elapsed.
Mode Toggle: the toggle that will toggle the mode between load and save mode.
Step 2: Other Script Members
We will create other members that won't be visible in the inspector.
public class InfiniteSavesExample : MonoBehaviour
{
private const string timeElapsedKey = "TimeElapsed";
[SerializeField]
private Button saveSlotPrefab;
[SerializeField]
private Button saveSlotCreator;
[SerializeField]
private Transform content;
[SerializeField]
private Text timeElapsedText;
[SerializeField]
private Toggle modeToggle;
private List<Button> slots = new();
private float timeElapsed;
private bool loadMode { get => modeToggle.isOn; }
}
timeElapsedKey: the key (or ID) of the time elapsed for saving purposes.
slots: a list of buttons that will store all of the instantiated save slots.
timeElapsed: the time elapsed as a float.
loadMode: the isOn value of the toggle.
If load mode is true, we will make the save slots load a save. If it's false (save mode), we will make the save slots overwrite a save.
Step 3: Instantiate Existing Saves
When we enter play mode, we need to first load any existing saves that the player may have made in a previous session.
We can do this using the Start method.
private void Start()
{
// Instantiate slots for existing saves
foreach (var save in SaveStorage.instance.saves.Values)
{
CreateNewSaveSlot(save);
}
}
Step 4: Increment Time
In the Update method, we will increment the time elapsed. This will be the only data that will be saved and loaded for this example.
private void Update()
{
// Increment time per frame
timeElapsed += Time.deltaTime;
timeElapsedText.text = $"Time Elapsed: {timeElapsed}";
}
Step 5: Saving and Loading Data
We will create 3 methods for saving and loading. The first one will load the data from a save file.
/// <summary>
/// Loads a save.
/// </summary>
/// <param name="saveFile">The save file.</param>
public void LoadSave(SaveFile saveFile)
{
timeElapsed = saveFile.GetData<float>(timeElapsedKey);
}
The second one will save (or overwrite) the data in the save file.
/// <summary>
/// Overwrites a save.
/// </summary>
/// <param name="saveFile">The save file.</param>
public void OverwriteSave(SaveFile saveFile)
{
// Save the time elapsed
saveFile.AddOrUpdateData(timeElapsedKey, timeElapsed);
saveFile.Save();
}
The third one will be used by the save slots and will load or overwrite the data depending on the mode.
/// <summary>
/// Loads or overwrites the save based on the active mode.
/// </summary>
/// <param name="saveFile">The save file.</param>
public void LoadOrOverwriteSave(SaveFile saveFile)
{
if (loadMode)
{
LoadSave(saveFile);
}
else
{
OverwriteSave(saveFile);
}
}
Step 6: Create New Save
We have methods that require a save file, but no save file is being created yet. A save file should be created when the 'Create New Save' button is pressed, along with a save slot.
So, let's create some methods for this. The first method will create a new save file.
/// <summary>
/// Creates a new save.
/// </summary>
public void CreateNewSave()
{
// Create the save file data
SaveFileSetupData saveFileSetupData = new()
{
fileName = $"InfiniteExampleSave{SaveStorage.instance.saveCount}",
saveLocation = SaveLocation.DataPath,
filePath = "StylishEsper/ESave/Examples/Any RP Examples",
fileType = FileType.Json,
encryptionMethod = EncryptionMethod.None,
addToStorage = true
};
SaveFile saveFile = new SaveFile(saveFileSetupData);
// Save the time elapsed
// Techincally, nothing is being overwitten at this stage since it is an empty save file
OverwriteSave(saveFile);
// Create ths save slot for this data
CreateNewSaveSlot(saveFile);
}
At the end, CreateNewSaveSlot is called. This has not been created yet. The CreateNewSaveSlot method will instantiate a new save slot, edit the save slot's text, and give the save slot an on-click event that will call LoadOrOverwriteSave.
/// <summary>
/// Creates a save slot for a save file.
/// </summary>
/// <param name="saveFile">The save file.</param>
public void CreateNewSaveSlot(SaveFile saveFile)
{
// Instantiate the save slot
var slot = Instantiate(saveSlotPrefab, content);
var slotText = slot.transform.GetChild(0).GetComponent<Text>();
slotText.text = $"Save Slot {slots.Count}";
// Move save creator to the bottom
saveSlotCreator.transform.SetAsLastSibling();
// Add on-click event for loading
slot.onClick.AddListener(() => LoadOrOverwriteSave(saveFile));
slots.Add(slot);
}
We still need the save slot creator button to have an on-click event that creates a new save. This can be done by updating our Start method.
private void Start()
{
// Instantiate slots for existing saves
foreach (var save in SaveStorage.instance.saves.Values)
{
CreateNewSaveSlot(save);
}
// Save slot creator on-click event
saveSlotCreator.onClick.AddListener(CreateNewSave);
}
Done! You can now test it in play mode.
Last updated