Use PlayerPrefs to read and write data

Page update date :
Page creation date :

Verification environment

Windows
  • Windows 11
Unity Editor
  • 2021.3.3f1
Input System Package
  • 1.3.0

Prerequisites for this tip

The following settings have been made in advance as a premise for the description of this tip.

At first

If you've played games, most of you have experienced it. You've probably paused a game and saved or loaded your play data to leave off.

When creating a game, you usually need to create this save and load function, set options, etc. Here, we will try to achieve this using the simplest PlayerPrefs way to store and load data.

UI Placement

Here, we will try to save or read the input contents by placing the input items and buttons and clicking the button. For the time being, you only need at least two buttons and one input field, so feel free to place them.

Preparing for UI Processing

First, let's implement the save button. How to create a button event is introduced in the following tips, so I will only list the relevant parts.

Leave the script name ButtonEvent as .

The script looks like this:

using UnityEngine;
using UnityEngine.UI;

public class ButtonEvent : MonoBehaviour
{
  /// <summary>名前入力フィールド。</summary>
  [SerializeField] InputField InputFieldName;

  /// <summary>HP 入力フィールド。</summary>
  [SerializeField] InputField InputFieldHP;

  /// <summary>攻撃力入力フィールド。</summary>
  [SerializeField] InputField InputFieldAttack;

  /// <summary>お金入力フィールド。</summary>
  [SerializeField] InputField InputFieldMoney;

  /// <summary>
  /// 保存ボタンをクリックしたときの処理。
  /// </summary>
  public void OnClickSave()
  {
  }

  /// <summary>
  /// 読み込みボタンをクリックしたときの処理。
  /// </summary>
  public void OnClickLoad()
  {
  }
}

Since it is necessary to get or set the entered value, prepare it as a field. Also, include the method that will be called when you click each button.

Attach your EventSystem script to and set each input field. It can be any object you want to attach.

Set each method to be called when the button is clicked.

Save the value

Now that the method is called when OnClickSave the save button is clicked, the process of the save button is as follows.

/// <summary>
/// 保存ボタンをクリックしたときの処理。
/// </summary>
public void OnClickSave()
{
  // 各値を指定したキーに保存します
  PlayerPrefs.SetString("Name", InputFieldName.text);
  PlayerPrefs.SetString("HP", InputFieldHP.text);
  PlayerPrefs.SetString("Attack", InputFieldAttack.text);
  PlayerPrefs.SetString("Money", InputFieldMoney.text);

  // 設定したデータを確定して保存します
  PlayerPrefs.Save();
}

PlayerPrefs.SetString The method is set to a key and a value to be saved. The key is specified when loading the saved data. SetString Here we are calling the method because the value to be stored is a string. int float If you want to SetInt save a value of another type, such as and , there are methods such as and SetFloat , so call them according to the type.

PlayerPrefs.Save Finally, call the method to confirm the save. Actually, it may be saved even if you do not call this method, but it is safer to call it.

However, even if you run the game at this point, it will only save the value, so you will not know if it was saved properly. If you check the saved location, you can see the data, but ...

Get a saved value

Next, implement the process of loading the saved data. The processing of the button is the same as the save process, so only the code of the loading process is described here.

/// <summary>
/// 読み込みボタンをクリックしたときの処理。
/// </summary>
public void OnClickLoad()
{
  // 指定したキーから値を読み込みます
  InputFieldName.text = PlayerPrefs.GetString("Name");
  InputFieldHP.text = PlayerPrefs.GetString("HP");
  InputFieldAttack.text = PlayerPrefs.GetString("Attack");
  InputFieldMoney.text = PlayerPrefs.GetString("Money");
}

Use the method to PlayerPrefs.GetString load the saved data. You can get the value saved with that key by specifying the key specified in Save as an argument. The value is retrieved in the return value of the method.

This is also saved as a string in the same way as when saving, so GetString we call the method. int float If you GetIntGetFloat are saving with or , call the method.

The retrieved value is reflected in the input field.

You can now save and load the data. I don't think there are any difficult elements.

Try moving it

Run to enter, save, and load. The saved data is persisted and should be able to be loaded even if you exit and rerun the game. If you can confirm the following pattern, I think there is no problem.

  1. Enter a value
  2. Click the Save button
  3. Change the value you entered
  4. Click the import button to confirm that it returns to the saved value.
  5. Exit the game
  6. Re-run the game and click the load button to see if you can recall the saved value
  7. Enter a different value, save it, and check if you can read the same with the updated value

Save and load a chunk of data

In the sample so far, only a few parameters have been saved. As you actually make a game, the number of parameters to be saved will increase steadily, and if you read and write them one by one, the code will be enormous. Therefore, when creating data to be actually saved, the theory is to combine the data to be saved into one and then write it all at once.

First, create a save data structure as a class. The goal is to be able to read and write data at once, but also to classify the data to make it easier for code to access each piece of data.

The following are examples of save game classes: It can be written anywhere it can be referenced from other code. This class structure is a sample, so in a real game you need to create it for your game.

/// <summary>セーブデータクラス。</summary>
public class SaveData
{
  public List<Character> Characters;
  public long Money;
}

/// <summary>1キャラクターの情報。</summary>
[Serializable]
public class Character
{
  public string Name;
  public int HP;
  public int Attack;
}

In the List Unity standard function used this time, if you define arrays or to have multiple unique classes, System.Serializable If you do not add an attribute, it will not be converted correctly, so Character I set the attribute to the Serializable class.

After you create the class, create the data to save. Of course, you can have instances of this class throughout the game. This depends on how the game is made.

// 保存するデータ作成
var saveData = new SaveData
{
  Money = 10000,
  Characters = new List<Character>
  {
    new Character { Name= "レイシア", HP = 50, Attack = 40, },
    new Character { Name= "アイリ", HP = 56, Attack = 27, },
    new Character { Name= "ニール", HP = 72, Attack = 36, },
    new Character { Name= "トリー", HP = 61, Attack = 30, },
  },
};

After setting JsonUtility.ToJson the data in the instance of the class, convert (serialize) it to a JSON string with the method. Since the value of the object is a single "string" called JSON with a data structure, allPlayerPrefs.SetString the data can be written with a single call to the method.

// オブジェクトを JSON 文字列に変換します
var saveJson = JsonUtility.ToJson(saveData);

// データを保存します
PlayerPrefs.SetString("SaveData", saveJson);
PlayerPrefs.Save();

However, since all the data is collected in one, it is not possible to save only part of it or read only part of it. Therefore, it is preferable to make it a unit that is easy to summarize, such as combining it as one object for one save data.

When reading the saved data, you can do the reverse processing when saving. The data to be read is a single string, but the contents are JSON-formatted data structures, so JsonUtility.FromJson they can be converted (deserialized) into class instances by methods. However, since we do not FromJson have information in the string what class to convert to, we must specify the type when calling the method.

// データを読み込みます
var loadJson = PlayerPrefs.GetString("SaveData");

// JSON 文字列からオブジェクトにデシリアライズします
var newData = JsonUtility.FromJson<SaveData>(loadJson);

If you try to move it, you can see that it is saved correctly and can be loaded.

By the way, we are using the Unity standard JsonUtility classes this time, but they may not be able to convert classes with complex data structures because they are not very functional. In that case, it is recommended to use other libraries.

Where is data stored?

PlayerPrefs When you use a class to store data, the location where it is saved depends on the platform you are running on. Please refer to the official page below for where it is actually stored.

In some environments, such as Windows, they are not stored in a file, but in system settings such as the registry. Since it is not a file, it is not suitable for saving saved data in , for example, if the save data is very large or PlayerPrefs you want to synchronize the save data with another environment. Conversely, if the data to be saved is the size of the option level, or if it is a standalone game that is completed only in the environment in which it is running, I think it is PlayerPrefs possible to save the data in .

In addition, the path of the saved location may be affected by the "CompanyName" and "ProductName" settings. If you want to publish your game, you need to decide on these values well in advance and not change them once you publish your game.

About data encryption

Data stored is not automatically encrypted. If the player's abilities are saved as they are, the user will freely rewrite the values, which will affect the game.

Do you need to encrypt, and if so, what level of strength is required, and how do you handle the encryption key? Things to consider vary from game to game.

I will not explain the encryption method here, but if you look it up on the Internet, it is a major language and tool, so I think there are various methods. For the time being, if you do not understand the meaning of the stored contents even if you open the file, and if you tamper with the data poorly, you will not be able to use the save data, I think that there will be some anti-fraud effect.