How to Save and Load a Game in Unity

Learn how to save and load a game in Unity using PlayerPrefs, Serialization and JSON. Complete your user’s experience by allowing them to save their game. By Anthony Uccello.

Leave a rating/review
Save for later
Share

Save a game with Unity

Games are getting longer and longer, with some having over 100 hours of content. It would be impossible to expect players be able to complete all of what a game has to offer in just one sitting. That’s why letting the player save their game is one of the most essential features your game should have — even if it’s just to keep track of their high scores.

But how does one create a save file and what should be in it? Do you need to use a save file to keep track of player settings too? What about submitting saves to the web so they can be downloaded later on a different device?

In this tutorial you will learn:

  • What serialization and deserialization are.
  • What PlayerPrefs is and how to use it to save player settings.
  • How to create a save game file and save it to disk.
  • How to load a save game file.
  • What JSON is and how you would use it.

It is assumed that you have some basic working knowledge of how Unity works (such as being able to create and open scripts), but other than that everything has been prepared so this tutorial will be very easy to follow. Even if you are new to C#, you should have no trouble keeping up except for a few concepts that might require further reading.

Note: If you are new to Unity or looking to pick up more Unity skills, you should checkout out our other Unity tutorials where you can learn about lots of Unity topics from C# to how the UI works.

Getting Started

Download the starter project here. You will be implementing the code for saving and loading the game, as well as the logic for saving the players settings.

Important Save Concepts

There are four key concepts to saving in Unity:

PlayerPrefs: This is a special caching system to keep track of simple settings for the player between game sessions. Many new programmers make the mistake of thinking they can use this as a save game system as well, but it is bad practice to do so. This should only be used for keeping track of simple things like graphics, sound settings, login info, or other basic user-related data.

Serialization: This is the magic that makes Unity work. Serialization is the conversion of an object into a stream of bytes. That might seem vague but take a quick look at this graphic:

Serialization illustration

What is an “object”? In this case an “object” is any script or file in Unity. In fact, whenever you create a MonoBehaviour script, Unity uses serialization & deserialization to convert that file down to C++ code and then back to the C# code that you see in the inspector window. If you’ve ever added [SerializeField] to get something to appear in the inspector, you now have an idea of what’s going on.

Note: If you’re a Java or web developer, you might be familiar with a concept known as marshalling. Serialization and marshalling are loosely synonymous, but in case you’re wondering what a strict difference would be, serialization is about converting an object from one form to another (e.g. an object into bytes), whereas marshalling is about getting parameters from one place to another.

Deserialization: This is exactly what it sounds like. It’s the opposite of serialization, namely the conversion of a stream of bytes into an object.

JSON: This stands for JavaScript Object Notation, which is a convenient format for sending and receiving data that is language agnostic. For example, you might have a web server running in Java or PHP. You couldn’t just send a C# object over, but you could send a JSON representation of that object and let the server recreate a localized version of it there. You’ll learn more about this format in the last section but for now just know that this simply a way of formatting data to make it multi-platform readable (like XML). When dealing with converting to and from JSON, the terms are JSON serialization and JSON deserialization respectively.

Player Prefs

This project has been set up so that all you will focus on is the logic for saving and loading games. However, if you are curious how it all works, don’t be afraid to open all the scripts and see whats going on, and feel free to ask a question here or in the forums if you need help.

Open the project, then open the Scene named Game and then click play.

Start menu

To start a game, click the New Game button. To play the game, you simply move your mouse, and the gun will follow your movement. Click the left mouse button to fire a bullet and hit the targets (which flip up and down at various time intervals) to get points. Try it out and see how high a score you can get in 30 seconds. To bring up the menu at any time, press the escape key.

game in progress

As fun as that game was, it might have been a little dry without music. You may have noticed that there is a music toggle, but it was switched off. Click play to start a new game, but this time click the Music toggle so it’s set to “On”, and you will hear music when you start your game. Make sure your speakers are on!

music toggle

Changing the music setting was simple, but click the play button again and you’ll notice a problem: the music is no longer checked. While you did change the music setting earlier, there was nothing keeping track of that change. This is the kind of thing that PlayerPrefs excels at.

Create a new script named PlayerSettings in the Scripts folder. Since you’ll be using some UI elements, add the following line at the top of the file with the other namespaces:

using UnityEngine.UI;

Next, add the following variables:

[SerializeField]
private Toggle toggle;
[SerializeField]
private AudioSource myAudio;

These will keep track of the Toggle and AudioSource objects.

Next add the following function:

  public void Awake ()
  {
    // 1
    if (!PlayerPrefs.HasKey("music"))
    {
      PlayerPrefs.SetInt("music", 1);
      toggle.isOn = true;
      myAudio.enabled = true;
      PlayerPrefs.Save ();
    }
    // 2
    else
    {
      if (PlayerPrefs.GetInt ("music") == 0)
      {
        myAudio.enabled = false;
        toggle.isOn = false;
      }
      else
      {
        myAudio.enabled = true;
        toggle.isOn = true;
      }
    }
  }

When set up, this will:

  1. Check if the PlayerPrefs has a cached setting for the “music” key. If there is no value there, it creates a key-value pair for the music key with a value of 1. It also sets the toggle to on and enables the AudioSource. This will be run the first time the player runs the game. The value of 1 is used because you cannot store a Boolean (but you can use 0 as false and 1 as true).
  2. This checks the “music” key saved in the PlayerPrefs. If the value is set to 1, the player had music on, so it enables the music and sets the toggle to on. Otherwise, it sets the music to off and disables the toggle.

Now Save the changes to your script and return to Unity.

Add the PlayerSettings script to the Game GameObject. Then expand the UI GameObject, followed by the Menu GameObject to reveal its children. Then drag the Music GameObject on to the Toggle field of the PlayerSettings script. Next, select the Game GameObject and drag the AudioSource over to the MyAudio field.

<Connect PlayerSettings script

The music is set up to work when the game runs (since there is code in the Awake function), but you still need to add the code if the player changes the setting during gameplay. Open the PlayerSettings script and add the following function:

  public void ToggleMusic()
  {
    if (toggle.isOn)
    {
      PlayerPrefs.SetInt ("music", 1);
      myAudio.enabled = true;
    }
    else
    {
      PlayerPrefs.SetInt ("music", 0);
      myAudio.enabled = false;
    }
    PlayerPrefs.Save ();
  }

This does almost the same as the code you wrote earlier, except it has one important difference. It checks the state of the music toggle and then updates the saved setting accordingly. In order for this method to be called, and thus for it to be able to do its work, you need to set the callback method on the Toggle GameObject. Select the Music GameObject and drag the Game GameObject over the object field in the OnValueChanged section:

Connecting the callback method

Select the dropdown which currently says No Function, and select PlayerSettings -> ToggleMusic(). When the toggle button in the menu is pressed, it will call the ToggleMusic function.

Selecting the right method

Now you’ve got things set up to keep track of the music setting. Click Play and try it out by setting the music toggle to on or off, then ending the play session and starting a new play session.

The game menu

The music setting is now properly saved! Great job — but you’re only getting started with the power of serialization.