Research / Design / Consulting

Many people starting their adventure with unity, encounter one of the most often problems - why Unity doesn't store points, money or other data?

Every time, you start your game, each script will be initialized according to default or values from the GameObject's Inspector. How can I store and accesses player preferences between game sessions? Unity built-in class – PlayerPrefs, can give us a hand (link: https://docs.unity3d.com/ScriptReference/PlayerPrefs.html).

Hello, I am PlayerPrefs and I would like to help you

PlayerPrefs Class allow us to store 3 simple data types:

  • float
  • int
  • string

On the one hand, it is a limited set of possibilities for us, but it is enought to do basic operations. Data is stored like in associative array – an abstract data type composed of a collection of pairs (key, value). What is important that each possible key appears at most once in the collection.

Store your data

PlayerPrefs Class provide developers several static methods which are responsible for storing and accessing data. We distinguish the following methods:

For store data

// C# Code
PlayerPrefs.SetInt(„KEY_NAME”, VALUE);
PlayerPrefs.SetFloat(„KEY_NAME”, VALUE);
PlayerPrefs.SetString(„KEY_NAME”, „VALUE”);

For access your data

// For access your data
int val = PlayerPrefs.GetInt(„KEY_NAME”);
float val = PlayerPrefs.GetFloat(„KEY_NAME”);
string val = PlayerPrefs.GetString(„KEY_NAME”);

As you can see, each method is based on the key under which our data is stored in the device's memory. The operation of the above methods is best checked in quick example.

PRZYKLAD

Once you have set this data you should save it. By default Unity writes preferences to device disk during OnApplicationQuit(). In cases when your game crashes, you might want to write the PlayerPrefs at sensible 'checkpoints' in your game. You can do it manually by method:

// C# Code
PlayerPrefs.Save();

It is not recommended to use Save() method every time when you set a new data. It will potentially causing a small hiccup.

Loading data

Loading is similar to saving – to load certain value simply use it unique key to find it:

// C# Code
float playerHealth = PlayerPrefs.GetFloat(„PlayerHealth”, 100.0f);

int playerGold = PlayerPrefs.GetInt(„PlayerGold”);

string playerName = PlayerPrefs.GetString(„PlayerName”);

What is also important is to note that we optionally can set a second parameter with custom default value. This value will be loaded when unique key not exist. If we didn’t use this parameter - PlayerPrefs will load default value of selected type.
Sometimes we need to know if given key exists. There is a very helpful method – HasKey():

// C# Code
PlayerPrefs.HasKey(„PlayerGold”);

This method returns true or false according to if we previously saved given key-value pair.

Removing data

The last of functionalities which PlayerPrefs class offers is removing entries from stored data. You can remove selected key-value pair by method:

// C# Code
PlayerPrefs.DeleteKey(„PlayerHealth”);

Also, You can remove all entries by:

// C# Code
PlayerPrefs.DeleteAll();

In this short description, I showed you how we use a PlayerPrefs class. Now, you know how to store data between the sessions ;)

Only float, int and string?! What if I want more?

Sometimes we want save more complex structures than 3 types of variables. What if I want to save bool value or more complex types like arrays or vectors? Of course you can code your PlayerPrefs extensions – for example - simple save and load of bool values.

// C# Code
bool myBool = true;

// saving
PlayerPrefs.SetInt(„myBool”, myBool == true ? 1 : 0);

// loading
myBool = PlayerPrefs.GetInt(„myBool”) == 1 ? true : false;

I assume that 1 is true and 0 is false. Then by conversion I can receive bool value from int. But in instance of arrays and vectors it will be harder sure? Thanks to Eric Haines from awesome Unity community. He created ArrayPrefs2 – a extended class of PlayerPrefs. Here you can find this class and it documentation.

With ArrayPrefs2 we can store types:

  • types from PlayerPrefs
  • Vector2
  • Vector3
  • Quaternion
  • Color
  • bool
  • and arrays of all types above.

Saving and loading in ArrayPrefs2 is simple like in original PlayerPrefs:

// C# Code
// Save bool value
PlayerPrefsX.SetBool(„myBool”,true);

// Load bool value
bool myBool = PlayerPrefsX.GetBool(„myBool”); 

Is PlayerPrefs secure?

This is a good question. If data is stored between session it must be saved somewhere of device memory. Is normal user can access to this data and cheat by change some values within? Unfortunately the answer is yes – PlayerPrefs is totally insecure. As amateur „hacker” can access and manually edit certain values. For the instance in Windows these values are stored in Windows Registry.

I am the H@ckerman!

The question is: How can I secure my prefs? In University of Games we using data encryption. Again you can by yourself code encrypted PlayerPrefs class with MD5 encryption for example, but good example is using EncyptedPlayerPrefs class created by Sven Magnus.

In another hand, you could simply use one of awesome plugins from assetstore:

  • Secured PlayerPrefs by Studio ZERO
  • PlayerPrefs Elite by UnityPlugins EU
  • EcryptPrefs – PlayerPrefs editor/encroptor by AvoEx
  • Armada PlayerPrefs by Dan Miller-Shroeder
  • EpicPrefs – PlayerPrefs on Steroids by Hot Totem Assets .

In my opinion it’s worth to invest in packages like above. Beyond encryption often we get other benefits like extended types and visual editor of stored values.

Conlusion

PlayerPrefs is very useful tool, which can be used to store basic values in your game. Base tool have some disadvantages like lack of security and small amount of value types to store. Fortunately Unity community take care of this class improvement. It is worth pointing out that PlayerPrefs is not an only way to persist data. Also, You can use serialization, .xml files or database but maybe I could write about that another time ;)

I hope it’s useful for you. If you have any comments or questions, please write them here!