Jump to content
  • Advertisement
  • entries
  • comments
  • views

Day 32 of 100 Days of VR: Learning about Saving and Loading Data in Unity

Josh Chang


Hello and welcome back to day 32!

Today is going to be an exciting day. We’re going to work on something that we’ve never seen before in any of the tutorials: Saving and Loading data in Unity!

Specifically, we’re going to save and load our high score from our game in Unity.

From this great Unity video on how to Save and Load data and my own research, I found 3 ways for us to save data:

  1. Using PlayerPrefs
  2. Using Data Serialization
  3. Using a Server

Now with our goals set, let’s get started!

Step 1: Saving with PlayerPrefs

In the first step, we’re going to look at some of the possible ways we can save and load data.

From this great Unity video on how to Save and Load data and my own research, I found 3 ways for us to save data:

Note: for step 1, none of the code will be used in our actual game.

In fact, we’re going to make a separate script just for this.

Step 1.1: Using PlayerPrefs

The first method is PlayerPrefs.

PlayerPrefs is a class that we call that allows us to save and load simple data (think numbers and string) across multiple game sessions.

We can think of PlayerPrefs as a dictionary/table object that takes in a key/value pairing.

For those who haven’t worked with something like this before, what this means is that PlayerPrefs is an object that we can store specific values to a string and when we want to get that value back, we can give it the string.

We’ll see how this works:

  1. In our GameManager game object, click Add Component and create a new TestSaveManager

In the code, we’re just going to store a value in and then print it out to our console.

Here it is:

using UnityEngine;

public class FakeSaveManager : MonoBehaviour
    void Start () {
	if (PlayerPrefs.HasKey("FakeScore"))
	    int savedScore = PlayerPrefs.GetInt("FakeScore");
	    print("We have a score from a different session " + savedScore);
	    PlayerPrefs.SetInt("FakeScore", 1337);
	    print("We don't have a score yet, so we're adding one in");

New Variables Used


Walking Through the Code

PlayerPrefs is a static object that we can just access. Here’s what we did:

  1. In Start() the first thing we did was check if we stored a value to our key string: FakeScore.

From here 2 things will happen.

First Run Through

The first time we run the code, we haven’t stored anything yet, so we’ll go to our else statement and set an Int with the value 1337 to our key FakeScore.

We also print in our console notifying us that it’s the first time we did that.

Now if we run the game for the first time, here’s what we’ll see:


Notice that it says we don’t have a score yet?

Second Run Through

Now after we ran the code for the first time and we added our key/value pair to our PlayerPrefs. If we were to run the code again, we’ll go to the other code path.

In the if statement, we’ll get the value we stored inside our key “FakeScore”, which is 1337.

We’ll print out 1337.

Play our game again and here’s what we get:


See how we have a score now? That means our score persisted from our previous game. Neat!

Step 1.2: Why use PlayerPrefs

Looking at what we’ve done, when do we want to use PlayerPrefs?

The benefit of PlayerPrefs is:

  • Fast and easy to use with no setup required to store primitive variables

The con of PlayerPrefs:

  • If the data we’re storing is important, the user can easily access the data and change it

Why is it insecure you might ask?

Well, it turns out that any data that we’re saving is saved in open space on your computer. In a Windows machine, you can find these values un-encrypted in our registry. Here it is:


Do you see the 2nd item from the top of the list FakeScore and the value is 1337.

Any computer savvy hacker who has knowledge of how Unity works can easily go in and make changes to these values to increase our score.

To summarize: Only use PlayerPrefs to store information that doesn’t really affect the game, such as player settings: brightness, audio sound, special effects, etc.

Do not use it to store things like high scores or sensitive information like your credit card information.

Step 2: Saving with Data Serialization

After looking at PlayerPrefs we have another method of storing data and that is using data serialization with the help of BinaryFormatter and FileStream class.

How this method works, is that we’re:

  1. Taking data (either an object we made serializable, a primitive value, or a JSON)
  2. Convert it to numbers
  3. Storing it somewhere in our device

We’ll discuss the details further down.

Step 2.1: Using Data Serialization

I’ve made some changes to our FakeSaveManager:

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;

public class FakeSaveManager : MonoBehaviour
	void Start () {
	    /*if (PlayerPrefs.HasKey("FakeScore"))
	        int savedScore = PlayerPrefs.GetInt("FakeScore");
	        print("We have a score from a different session " + savedScore);
	        PlayerPrefs.SetInt("FakeScore", 1337);
	        print("We don't have a score yet, so we're adding one in");

    private void SaveWithSerializer()
        BinaryFormatter formatter = new BinaryFormatter();
        print("Save location: " + Application.persistentDataPath);
        FileStream fileStream = File.Create(Application.persistentDataPath + "/save.dat");
        formatter.Serialize(fileStream, 1337);

    private void LoadWithSerializer()
        BinaryFormatter formatter = new BinaryFormatter();
        FileStream fileStream= File.Open(Application.persistentDataPath + "/save.dat", FileMode.Open);

        print("serializer got back: " + formatter.Deserialize(fileStream));

New Variables Used


Walking Through the Code

The first thing you might notice is that I commented out the PlayerPrefab code. We don’t need that anymore, we’re just going to focus on the serialization part.

Before we walk through the code, let’s talk about these individual classes that we’re using.


We can think of FileStream is a class that allows us to interact with files. In this case, use File.Create() and File.Open() to give us access to these files that we want to access.

Notice how we use something called Application.persistentDataPath when we create and open a file? persistentDataPath is a file location in our computer/phone that we can use to store our game files. Each path is different depending on the OS that the game is running on.

On a windows machine, here’s where the file would be saved to:


Notice how we called our file “save.dat”, that’s just what we call it, the file can be any format we want and it’ll still function the same way.

After we set up our FileStream, we will give it to our BinarySerializer so that it can use it to store our data.

It’s also important to remember that when we’re done using a FileStream, we should always call Close() to prevent a memory leak.


We can think of the BinaryFormatter class as a useful utility that takes in a FileStream and reads/write data into the file.

In our specific example, I put the float 1337 inside, but we can put in classes that we create ourselves.

However, if we were to create our own object, we must make sure we tell Unity to serialize it (by putting [Serialize] on top of the class name).

The two important function we have to know is Serialize() and Deserialize().

  • Serialize is how we change our data into binary and then store them in our File
  • Deserialize is how we read the data back from binary.

If we were to open the file that we saved data into, here’s what we have:


Now that we understand everything used, let’s walk through the code:

  1. In Start(), we call SaveWithSerializer() which uses a BinaryFormatter and a FileStream to help us store our data, which in this case is just a float value.
  2. We create a new FileStream with the path to where we want to save our data to. We use Application.persistentDataPath to give us a location to store our file that changes depending on what OS is running our game. This is Unity making sure we put our save files in the right location so we can access it back later no matter what platform we’re using.
  3. After we have our FileStream we would use the BinaryFormatter to Serialize our data to the path we specified. After that, make sure to close our FileStream to prevent memory leaks!
  4. After we save, we call LoadWithSerializer() we do a similar operation where we create a BinaryFormatter and a FileStream to the location of the file we previously saved.
  5. With these two objects, we Deserialize, which means we unencrypt our data and put it back into a usable form for us. At this point, we have our data back.

Step 2.2: Why Use Data Serialization?

At this point, you might guess why we might want to use Data Serialization:

  • Our data is encrypted so it’s harder for the players to find it and modify the file.
  • In our example, we only store one variable, but we can actually save a lot more than just that

However, just like the PlayerPrefab, the con is:

  • We know the location of the file, and just because it’s in binary, it doesn’t mean it can’t be reverse engineered!

When should we use Data Serialization?

The answer: almost everything! Data serialization can be used as a database for our equipment, magic spells, and more! We can also use it to store information about our player character.

My only caveat is that if the game you’re creating is multiplayer where you don’t want players to have an unfair advantage, then you DO NOT want to save data about the player locally.

We can store information that the game references where we don’t modify, such as stats of an equipment locally, however information like player inventory is best stored somewhere else.

Where is that somewhere else? Good question, that’s the topic of our next method.

Step 3: Saving Data to A Server

The final and last way for us to store data for our game are to save the data to an external web server which we control and access.

From the external server, we would keep track of the state of the player, for example:

  • What level they are
  • How much money they are
  • What items they have in their inventory

All information that is changeable by the player should be saved externally in a server, where we can do verifications to make sure the player is what they say they are.

Step 3.1: Using a Server

I’m not going to create a server, but rather discuss how we would do it if we wanted to.

The first thing we must do is host a web server online somewhere.

Once the server is up, from our game, ie the client, we would make HTTP network request to our server passing around whatever data our server requires.

A general flow of what we would expect is that:

  • Whenever we’re ready to save our data, we would send the data to our server
  • Whenever we want to load our data, we would make a request to our server for our data.

When sending data over the network, we can’t just send our whole class over, our web server have no idea what anything is.

To solve this problem, we’re going to have to convert our objects into a JSON object and then send it across the network.

I won’t go too deep into the details, but a JSON object is basically a string representation of our object that we can easily convert back and forth.

We would send this string to our server where we would parse it, validate the data, and then save it in the database.

When we’re loading information, the server would send a JSON object back to the game where we would also parse and change the JSON back into something we can use.

Step 3.2 Why use a server?

The benefit of using this approach to store our data is:

  1. Cheating is impossible. Assuming there are no vulnerabilities and we have good data checks, it’ll be very hard for the player to be able to modify their own data and have it saved on our server.
  2. Similar to Data Serialization, we can save more complex data than just primitive variables.

The cons are:

  1. We need a server, which costs money.
  2. There’s more overhead work needed. We need to create our own database, know how to set up a server, and deal with storing multiple players instead of one.

The big question here is: when should we use a server?

The answer: In any game that has multiplayer that we don’t want players to get an unfair advantage against each other. If not, there should be no problem to storing everything locally.


Today, we explored the options that are available to us to save data in a game.

The 3 ways we explored are:

  • PlayerPrefs
  • Data Serialization
  • Sever

Most likely, in a real game, we would use all 3, but the best way for me to summarize when to use each is:

Use PlayerPrefs to store player setting information that doesn’t affect the game itself.

Use Data Serialization to store database information that we will only reference, but not change

Use a Server when we have a multiplayer game where we want to ensure no one can cheat by sending all player data to a server where we can do validation on the authenticity of the data.

For a single player game, however, we can save the data in a serialized file or if it’s simple enough, even in our PlayerPrefs.

Now that we spent Day 32 looking at saving data, it’s finally time for us to start using it on Day 33!

I’ll see you all next time to start putting everything we learned into action!

Source: Day 32

Visit the 100 Days of Unity VR Development main page.

Visit our Homepage


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By Znippy
      Hello everyone!  
      This is my submission for the Frogger challenge.
      The final build for the project can be found here!
      I hope I have fulfilled all requirements for this challenge. Sadly, I do not have time to create a gameplay video. I am not sure if this is a must. I have added a couple of screenshots from my blog series.
      My post-mortem post will be done next week. 
      As I already mentioned on the project page, I also could offer a Linux build if somebody needs one!
      I hope you like it and I am excited to see your high scores!
      Please tell me if there is anything missing!
    • By horror_man
      Hello, I'm currently searching for a talented and passionate programmer to create a small but great horror game that would take around 3 months to be done.
      About the game: The game would be a sci-fi/post-apocalyptic survival horror 3D game with FPS (First person shooter) mechanics and an original setting and story based in a book (which I'm writing) scene, where a group of prisoners are left behind in an abandoned underground facility. It would play similar to Dead Space combined with Penumbra and SCP: Secret Laboratory, with the option of playing solo or multiplayer.
      Engine that'd be used to create the game: Unity
      About me: I'm a music composer with 4 years of experience and I'm fairly new in this game development world, and I'm currently leading the team that'd be creating this beautiful and horrifying game. I decided that making the book which I'm writing into a game would be really cool, and I got more motivated about doing so some time ago when I got a bunch of expensive Unity assets for a very low price. However, I researched about how to do things right in game development so I reduced the scope of it as much as I could so that's why this game is really based in a scene of the book and not the entire thing (and also that's why it would take 3 months). Also I'm currently learning how to use Unity and how to model things with Blender.
      Our team right now consists of: Me (Game Designer, Creator, Music Composer, Writer), 3 3D Modelers, 1 Sound Effect Designer, 1 Concept Artist and 1 Programmer.
      Who am I looking for:
      - A programmer that's experienced in C# and with Unity.
      Right now the game is very early in its development (GDD is completed and all 3D Items, Music and Sound Effects are completed).
      If you are interested in joining, contributing or have questions about the project then let's talk. You can message me in Discord: world_creator#9524
    • By Nilmani Gautam
      Welcome every one from this section we are going to develop a new 3D game Cube Race
    • By JustACicada
      Random Number God has been updated to v1.1.0.
      This is an incremental (although not idle) game about defeating randomized robots by rolling dice and playing cards that alter those dice and their effects.
      Other than performance fixes, the game has been rebalanced from the ground up. Now it should progress in a more fluid fashion. An option to reset the game with a significant boost to your power has been added, allowing you to advance further than you could before.
      There is also now an option to significantly speed up battle animations. Once you learn the rules of the game, a battle can easily take <2 min.
      Windows, Linux: https://justacicada.itch.io/random-number-god
      Android: https://play.google.com/store/apps/details?id=samuelVazquez.randomNumberGod

    • By Jamesgz
      Hey my dudes,
      Me and 4 friends are third year compsci students. Three of us are pretty good at drawing. We are hoping to make a 2d roguelite game with unity during the next few months. We are still brainstorming. At the moment, my idea is to create a card roguelite game:
      First, you would need to choose 2 heroes to enter the dungeon with the goal of finding a treasure. The treasure found gives you extra bonus in later runs. You can choose between mage, gunner, rogue, paladin, warrior and fighter. Each hero has their own unique cards. And there are common cards that every heroes can get(like hearthstone).
      The progression system would be like slay the spire’s. You can choose your own path, but every paths leads to the boss. It would use procedural generation. After defeating an enemy, you get to choose a new card out of the three options. There would be shops, random events, elite enemies, etc
      The combat system is where i need some suggestions on. There would be two piles of deck. One for each hero. I can think of two good combat systems:
      1. Before every enemy encounters, you can choose what cards to use from your deck. Cards not used would not get discarded. Cards are drawn from the deck only if they break or due to special card’s effect. Every card have a durability number. Ones the durability reach zero, the card would break and can no longer be used. Events/enemies can modify the durability of the cards.
      2. Card not used this turn would get discarded. Once the deck is empty, the discard pile gets shuffled and copied to the deck. Card/item effects can increase the number of cards you draw.
      How can I make the game more interesting? Any suggestions would be appreciated.

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!