Creating a Load/Save Game system in Unity
I won't go into too much detail about the Save Dialog window, since it can be created however you like, but here is a quick overview. The Save dialog is pretty basic and consist of a set of three Save (floppy disk) icons and a back option to close the dialog, with four corresponding hands.
I iterate through the save options using a List:
List<int> saveSlots = new List<int>{
1,2,3,4
};
selectPreviousSave()
and selectNextSave()
are called for the left and right keys:
public void selectPreviousSave(){
if(manager.GetComponent<gamemanager>().loadDialogIsShowing){
saveSlotNumber--;
}
// If player tries to go past first entry/save slot, jump back to the last save slot
if(saveSlotNumber < 0){
saveSlotNumber = saveSlots.Count - 1;
}
chosenSaveSlot = saveSlots[saveSlotNumber];
I set the corresponding save slot hand to active and deactivate the other hands when an option is selected:
if(chosenSaveSlot == 1){
// Save Slot 01
saveHand01.SetActive(true);
saveHand02.SetActive(false);
saveHand03.SetActive(false);
saveHand04.SetActive(false);
}
When a Save slot is chosen, I call chooseSaveOption()
, which in turn calls
SaveGame()
on the chosen Save slot:
void chooseSaveOption(){
if(chosenSaveSlot == 1){
// Save Slot 01
SaveGame(chosenSaveSlot);
}
...
SaveGame()
first checks that the current Save slot isn't full. If the Save slot is empty, it immediately writes the current checkpoint floor to the matching PlayerPref
variable. If the Save slot is full, it displays a confirmation window to confirm that the player wants to overwrite the Save slot:
// Save the GameState parameters to the passed Save slot
void SaveGame(int saveslot){
// Create a new GameState
GameState gameState = new GameState(manager.GetComponent<gamemanager>().checkpointFloor, saveslot);
// Check if the Save slot has already been saved to
gameslotFull = gameState.CheckSaveSlot();
if(saveslot == 1){
// if gamestate already exist, confirm that the player wants to overwrite it
if(gameslotFull){
// Display Save Confirmation
displayConfirmationWindow();
}
// If the save slot is empty, save to the slot
if(!gameslotFull){
gameState.SaveGameState();
// Update Save slot text to display new saved floor
saveSlot01Text.GetComponent<unityengine.ui.text>().text = "FLOOR " + manager.GetComponent<gamemanager>().checkpointFloor;
}
}
if(saveslot == 2){
// if gamestate already exist, confirm that the player wants to overwrite it
if(gameslotFull){
// Display Save Confirmation
displayConfirmationWindow();
}
// If the save slot is empty, save to the slot
if(!gameslotFull){
gameState.SaveGameState();
// Update Save slot text to display new saved floor
saveSlot02Text.GetComponent<unityengine.ui.text>().text = "FLOOR " + manager.GetComponent<gamemanager>().checkpointFloor;
}
}
if(saveslot == 3){
// if gamestate already exist, confirm that the player wants to overwrite it
if(gameslotFull){
// Display Save Confirmation
displayConfirmationWindow();
}
// If the save slot is empty, save to the slot
if(!gameslotFull){
gameState.SaveGameState();
// Update Save slot text to display new saved floor
saveSlot03Text.GetComponent<unityengine.ui.text>().text = "FLOOR " + manager.GetComponent<gamemanager>().checkpointFloor;
}
}
}
Each Save slot is created with an instance of GameState
(a custom class):
public class GameState
{
// Basic constructor for loading a saved game
public GameState(int loadslot){
this.loadslot = loadslot;
}
// Overloaded constructor for saving a GameState
public GameState(int floor, int saveslot){
this.floor = floor;
this.saveslot = saveslot;
}
}
CheckSaveSlot()
checks if the matching PlayerPref
variable (i.e. the checkpoint floor) is greater than 0, meaning it has been written to (the lowest checkpoint floor possible is 1).
If it's 0, saveslotFull
is false. If it's greater than 0, saveslotFull
is true.
The method returns saveslotFull:
// Return whether a GameState slot is already saved to
public bool CheckSaveSlot(){
// Get the proper PlayerPref based on the saveslot passed in the constructor
if(saveslot == 1){
saveslotStatus = PlayerPrefs.GetInt("savedCheckpointFloor01", 0);
}
if(saveslot == 2){
saveslotStatus = PlayerPrefs.GetInt("savedCheckpointFloor02", 0);
}
if(saveslot == 3){
saveslotStatus = PlayerPrefs.GetInt("savedCheckpointFloor03", 0);
}
// If the saved checkpoint floor is 0, then the save slot hasn't been written to
if(saveslotStatus == 0){
saveslotFull = false;
}
// If the saved checkpoint floor > 0, then the save slot has been written to
if(saveslotStatus > 0){
saveslotFull = true;
}
return saveslotFull;
}
SaveGameState()
writes the current checkpoint floor to the corresponding PlayerPrefs
variable:
// Save the checkpoint floor to the chosen Save slot
public void SaveGameState(){
// Write to PlayerPrefs
if(saveslot == 1){
PlayerPrefs.SetInt("savedCheckpointFloor01", floor);
PlayerPrefs.Save();
}
if(saveslot == 2){
PlayerPrefs.SetInt("savedCheckpointFloor02", floor);
PlayerPrefs.Save();
}
if(saveslot == 3){
PlayerPrefs.SetInt("savedCheckpointFloor03", floor);
PlayerPrefs.Save();
}
}
Finally, to load a game, I create a new instance of GameState
and call LoadGameState()
on the chosen Save slot, which sets the checkpoint floor to the checkpoint floor of the corresponding PlayPref
variable, and then starts the game on the selected checkpoint floor:
// Call LoadGameState() on selected GameState
void LoadGame(int loadslot){
// Load Game State
GameState gameState = new GameState(loadslot);
gameState.LoadGameState();
callHideLoadDialog();
// Start the game with the checkpoint floor not set
// to the PlayPref checkpoint floor for that slot
PlayGame();
}
GameState.cs
// Set the checkpoint floor to the checkpoint floor of the current Save slot
public void LoadGameState(){
manager = GameObject.FindWithTag("gameManager");
// Read PlayerPrefs
if(loadslot == 1){
floor = PlayerPrefs.GetInt("savedCheckpointFloor01", 0);
// Set checkpoint floor to checkpoint floor in GameState
manager.GetComponent<gamemanager>().checkpointFloor = floor;
}
if(loadslot == 2){
floor = PlayerPrefs.GetInt("savedCheckpointFloor02", 0);
// Set checkpoint floor to checkpoint floor in GameState
manager.GetComponent<gamemanager>().checkpointFloor = floor;
}
if(loadslot == 3){
floor = PlayerPrefs.GetInt("savedCheckpointFloor03", 0);
// Set checkpoint floor to checkpoint floor in GameState
manager.GetComponent<gamemanager>().checkpointFloor = floor;
}
}
Below is the complete GameState
Class for reference:
Complete GameState.cs
public class GameState
{
int floor;
int saveslot;
int loadslot;
int saveslotStatus = 0;
GameObject manager;
bool saveslotFull = false;
void Start(){
manager = GameObject.FindWithTag("gameManager");
}
// Basic constructor for loading a saved game
public GameState(int loadslot){
this.loadslot = loadslot;
}
// Overloaded constructor for saving a GameState
public GameState(int floor, int saveslot){
this.floor = floor;
this.saveslot = saveslot;
}
// Return whether a GameState slot is already saved to
public bool CheckSaveSlot(){
// Get the proper PlayerPref based on the saveslot passed in the constructor
if(saveslot == 1){
saveslotStatus = PlayerPrefs.GetInt("savedCheckpointFloor01", 0);
}
if(saveslot == 2){
saveslotStatus = PlayerPrefs.GetInt("savedCheckpointFloor02", 0);
}
if(saveslot == 3){
saveslotStatus = PlayerPrefs.GetInt("savedCheckpointFloor03", 0);
}
// If the saved checkpoint floor is 0, then the save slot hasn't been written to
if(saveslotStatus == 0){
saveslotFull = false;
}
// If the saved checkpoint floor > 0, then the save slot has been written to
if(saveslotStatus > 0){
saveslotFull = true;
}
return saveslotFull;
}
// Save the checkpoint floor to the chosen Save slot
public void SaveGameState(){
// Write to PlayerPrefs
if(saveslot == 1){
PlayerPrefs.SetInt("savedCheckpointFloor01", floor);
PlayerPrefs.Save();
}
if(saveslot == 2){
PlayerPrefs.SetInt("savedCheckpointFloor02", floor);
PlayerPrefs.Save();
}
if(saveslot == 3){
PlayerPrefs.SetInt("savedCheckpointFloor03", floor);
PlayerPrefs.Save();
}
}
// Set the checkpoint floor to the checkpoint floor of the current save slot
public void LoadGameState(){
manager = GameObject.FindWithTag("gameManager");
// Read PlayerPrefs
if(loadslot == 1){
floor = PlayerPrefs.GetInt("savedCheckpointFloor01", 0);
// Set checkpoint floor to checkpoint floor in GameState
manager.GetComponent<gamemanager>().checkpointFloor = floor;
}
if(loadslot == 2){
floor = PlayerPrefs.GetInt("savedCheckpointFloor02", 0);
// Set checkpoint floor to checkpoint floor in GameState
manager.GetComponent<gamemanager>().checkpointFloor = floor;
}
if(loadslot == 3){
floor = PlayerPrefs.GetInt("savedCheckpointFloor03", 0);
// Set checkpoint floor to checkpoint floor in GameState
manager.GetComponent<gamemanager>().checkpointFloor = floor;
}
}
}
Files
Get Elevader
Elevader
A crazed A.I. has trapped you on an elevator. Jump, dodge, and dive to stay alive! Can you survive?
More posts
- Elevader v2.0 publishedJun 09, 2022
- Elevader is published!!!Jun 06, 2022
- Adding an Old School Instruction Manual to ElevaderMar 23, 2022
- Creating a High Score System in UnityFeb 12, 2022
- Making CutscenesDec 01, 2021
- Elevader: Jump, dodge, and dive to survive the crazed A.I.Nov 28, 2021
Leave a comment
Log in with itch.io to leave a comment.