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:
Using PlayerPrefs
Using Data Serialization
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:
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);
}
else
{
PlayerPrefs.SetInt("FakeScore", 1337);
print("We don't have a score yet, so we're adding one in");
}
}
}
New Variables Used
None
Walking Through the Code
PlayerPrefs is a static object that we can just access. Here’s what we did:
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 FileStreamclass.
How this method works, is that we’re:
Taking data (either an object we made serializable, a primitive value, or a JSON)
Convert it to numbers