Saving Game and Settings in Unreal Engine 5 with C++
Saving your game is crucial to allow players to take a break from your game, and then get back to where they left off without having to start from the beginning. Both the blueprint method and C++ methods are quite similar, however with C++ there are a few things to look out for.
For this example, I will use my PracticeRange project, in which I wanted to save the player’s mouse sensitivity and whether they wanted to invert their mouse. The first thing to do is to create a C++ class inheriting from the SaveGame class. I’m going to call mine MySaveGame. Next you want to declare variables to store whatever values you want to save. In my case, those are a float MouseSens and bool bInvertMouse. THESE VARIABLES MUST BE DECORATED WITH THE UPROPERTY() MACRO!
Next, we want to open the cpp file of the class who’s data we want to store, in my example this is my PlayerCharacter class. We are now going to create two functions: SaveGame() and LoadGame().
Starting with SaveGame(), we want to first check if a save file already exists using DoesSaveGameExist() from the UGameplayStatics library. This function as well as some others involved with saving the game take in an FString called SlotName. This slot name is the name of your save file and must the the same in all of the functions we will use. You could use separate slot names to store different things, for example having one settings, and one for a player inventory.
If a save file exists, we want to load it into an instance of our custom MySaveGame class, which is done by using the LoadGameFromSlot() function. Since this returns a SaveGame*, we need to cast it to our created MySaveGame class. This then allows us to access the variables we declared within said class and set them to the values we want to save. Lastly we want to commit those variables and save them into a file, which is done using SaveGameToSlot().
In the case that a save file doesn’t exist, we want to create a new save file using CreateSaveGameObject() and follow the steps above. This function takes a TSubclassOf type USaveGame, so we can pass in a static class of our created MySaveGame class. Next we cast this to our created class, set the variables we would like to save and finally save the variables to a file. Additionally you could add debug messages to help with debugging and understanding how the code works.
Loading the game follows a similar logic. We check if a save file exists and it the case that it doesn’t, we print a log message saying no such file exists. If a file does exist, we once again want to load it into an instance of our created MySaveGame class. From there, we can access the data from the SaveGameInstance and set them to whatever data we want to load. In this case those being the player’s MouseSens and bInvertMouse.
Now with the main functionality implemented, it’s a matter of calling SaveGame() and LoadGame() at appropriate times in your game. In my project LoadGame() is called inside the player actor’s BeginPlay(), while SaveGame() is called after the player changes any of the settings in the settings menu.