この記事について

この記事では UnityのPlayerPrefs を使ってデータを保存・読み込み・削除する方法について解説します。
BGMの音量やオプション設定など、少量のデータを残したいときに便利なUnity標準の仕組みです。
保存場所やSaveを呼ぶタイミング、保存されないときの確認点も紹介します。

PlayerPrefsで保存したInt・Float・StringをWindowsのレジストリエディターで確認した画面

先に押さえておきたいこと

  • PlayerPrefsはint・float・stringを保存できます
  • 未保存のキーをGetで読み込むと、エラーではなく初期値が返ります
  • データは暗号化されません。パスワードなどの機密情報は保存しないでください

この記事でわかること

  • PlayerPrefs とは何か
  • 保存できるデータ型(int, float, string)
  • 保存・読み込み・削除と、初期値・HasKeyの使い分け
  • Saveを呼ぶタイミングと、OSごとの保存場所
  • 保存されないときに確認すること

データの保存とは?

Unityで使用できるデータの保存方法は複数あります。この記事ではPlayerPrefsを扱いますが、JSONファイルなどを含めた保存方法の全体像は、以下の記事を参考にしてください。

PlayerPrefsとは?保存できる型と向いている用途

PlayerPrefs は、Unity が提供する 簡易的な永続データ保存機能 です。
データは端末(PCやスマホ)のローカルに保存され、アプリを終了しても保持されます。

保存できるデータ型は以下の3種類です。

  • int(整数)
  • float(小数)
  • string(文字列)

BGMの音量、表示設定、チュートリアルを見たかどうかなど、少量の設定を端末に保存する用途に向いています。アカウントをまたいだ共有や、別端末への引き継ぎを自動で行う機能ではありません。

PlayerPrefsの保存場所【Editor・ビルド・OS別】

PlayerPrefsの保存場所は、OSとEditor/ビルドしたアプリの違いによって変わります。Windowsでは「Company Name」と「Product Name」が保存先に関係します。まずはProject Settings > Playerの設定を確認しておきましょう。

UnityのProject SettingsでCompany NameとProduct Nameを確認する画面

保存場所の代表例は以下の通りです。Unity 6の公式資料をもとに整理しています。

実行環境保存場所・仕組み
Windows(ビルド)レジストリ:HKEY_CURRENT_USER\Software\[CompanyName]\[ProductName]
Windows(Editor)レジストリ:HKEY_CURRENT_USER\Software\Unity\UnityEditor\[CompanyName]\[ProductName]
macOS(ビルド)~/Library/Preferences/[BundleIdentifier].plist
既定のBundle Identifierはcom.[CompanyName].[ProductName]
macOS(Editor)~/Library/Preferences/com.[CompanyName].[ProductName].plist
iOSNSUserDefaultsを使用
AndroidSharedPreferences:/data/data/[package-name]/shared_prefs/[package-name].v2.playerprefs.xml
Linux~/.config/unity3d/[CompanyName]/[ProductName]
Windows(UWP)%userprofile%\AppData\Local\Packages\[ProductPackageId]\LocalState\playerprefs.dat
Web(WebGL)ブラウザーのIndexedDB。PlayerPrefsとして保存できるデータは最大1MB

表の[CompanyName]などは、自分のプロジェクトの値に置き換えてください。スマートフォンの保存先は通常のファイル操作で開けるとは限りません。JSONなどの保存に使うApplication.persistentDataPathとは別の仕組みです。

参考:Unity公式:PlayerPrefsの保存場所

WindowsのEditorで保存した値を確認する

それでは、Windows 11でUnity EditorのPlay Modeから保存した値を確認してみましょう。

  1. 「Windows + R」で「ファイル名を指定して実行」を開き、「regedit」と入力してレジストリエディターを開く
  2. 「HKEY_CURRENT_USER」→「Software」→「Unity」→「UnityEditor」→「Company Name」→「Product Name」
WindowsのUnity Editor用PlayerPrefs保存先をレジストリエディターで開いた画面

ここでは保存先を確認するだけにしましょう。レジストリを直接編集・削除せず、初期化するときは後述のDeleteKeyなどで対象のキーを指定してください。

PlayerPrefsの使い方【保存・読み込み・削除】

PlayerPrefsの準備

まずはヒエラルキーで右クリックをして空のGameObjectを1つ用意します。
・「右クリック」→「Create Empty」

次にData_PlayerPrefs.csというスクリプトを作成して、先ほどの空のGameObjectにアタッチしてください。
以下は同じスクリプトを順番に書き換えて試す例です。同名のクラスを複数作らず、Playを止めてからコードを変更してください。

空のGameObjectにPlayerPrefs用スクリプトを追加する準備画面

データを保存する(Set)

値の設定には「SetInt , SetFloat , SetString」を使用します。SetIntなどの第1引数にはキー、第2引数には保存する値を指定します。データを扱うときは第一引数を「Key(キー)」、第二引数を「Value(バリュー)」と言うことが多いです。

using UnityEngine;

public class Data_PlayerPrefs : MonoBehaviour
{
    void Start()
    {
        // int型の保存
        PlayerPrefs.SetInt("Int", 100);

        // float型の保存
        PlayerPrefs.SetFloat("Float", 0.8f);

        // string型の保存
        PlayerPrefs.SetString("String", "Test");

        // 変更した値を端末へ書き込む
        PlayerPrefs.Save();
    }
}

実行してみると、それぞれデータが保存されましたね。
WindowsのEditorではキー名にハッシュ値が付く場合があります。レジストリ上の名前がコードと完全に同じ見た目でなくても、保存・読み込みにはコードで決めたキーを使います。

PlayerPrefsで保存したInt・Float・StringをWindowsのレジストリエディターで確認した画面

PlayerPrefs.Saveはいつ呼ぶ?

SetIntなどで値を設定した後、PlayerPrefs.Save()で変更した値を端末へ書き込みます。Unityには終了時などの自動保存もありますが、モバイルやWebでは終了処理が必ず実行されるとは限りません。

  • 設定の決定ボタンを押したときなど、値を確定するタイミングでSaveを呼ぶ
  • 書き込みで一時的に処理が止まることがあるため、Updateで毎フレーム呼ばない
  • 必要に応じて中断時にも保存し、対象の端末で再起動後の動作を確認する

ここまでのStartの例は動作確認用です。毎回同じ値をSetすると、起動のたびに保存済みの値を上書きします。再起動後に値が残るか確かめるときは、次の読み込み用コードに書き換えて試してください。

参考:Unity公式:PlayerPrefs.Save、OnApplicationQuitの注意点

データを読み込む(Get)と存在確認(HasKey)

データの読み込みには「GetInt・GetFloat・GetString」を使用します。キーが存在しない場合は、エラーではなく初期値が返ります。
「未保存」と「0などを保存済み」を区別したいときは、「HasKey」で存在を確認しましょう。

using UnityEngine;

public class Data_PlayerPrefs : MonoBehaviour
{
    void Start()
    {
        //存在するデータ
        if (PlayerPrefs.HasKey("Int"))
        {
            int i = PlayerPrefs.GetInt("Int");  //データの読み込み
            Debug.Log("データ: " + i);
        }

        //存在しないデータ
        if (PlayerPrefs.HasKey("Score"))
        {
            Debug.Log("データあり");
        }
        else
        {
            Debug.Log("データなし");
            int highScore = PlayerPrefs.GetInt("Score", 10);       // デフォルト値 10
        }

        //存在しないデータ
        if (PlayerPrefs.HasKey("Score"))
        {
            Debug.Log("データあり");
        }
    }
}

先ほどのIntを保存済みで、Scoreをまだ保存していなければ、Consoleに「データ: 100」「データなし」と表示されます。
GetInt(“Score”, 10)は、未保存なら10を返します。ただし、初期値を読み込むだけで、その値が保存されるわけではありません。そのため、後からHasKey(“Score”)を呼んでもfalseのままです。

PlayerPrefsのGetIntとHasKeyによる読み込み・存在確認のConsole出力

未保存のキーに返る初期値

  • GetInt:第2引数を省略すると0
  • GetFloat:第2引数を省略すると0.0f
  • GetString:第2引数を省略すると空文字(””)

音量を初回だけ1.0にしたい場合などは、第2引数に初期値を指定するとわかりやすくなります。以下はメソッド内で読み込む例です。

int score = PlayerPrefs.GetInt("Score", 0);
float volume = PlayerPrefs.GetFloat("BgmVolume", 1.0f);
string playerName = PlayerPrefs.GetString("PlayerName", "Player");

参考:Unity公式のGetInt・GetFloat・GetString

データを削除する(DeleteKey・DeleteAll)

データを扱う上でデータの削除も必須です。そのような時に特定のデータの削除「DeleteKey(“Key”)」、全てのデータを削除「DeleteAll」を使用します。

using UnityEngine;

public class Data_PlayerPrefs : MonoBehaviour
{
    void Start()
    {
        // 特定のキーを削除
        PlayerPrefs.DeleteKey("Int");
        PlayerPrefs.Save();
    }
}

実行してみるとIntだけ消えましたね。

PlayerPrefs.DeleteKeyでIntキーを削除した後のレジストリ

それでは最後に、PlayerPrefs全体を削除する方法です。DeleteAllは、そのアプリのPlayerPrefsに保存した設定をまとめて消します。他の設定も消えるため、テスト用のプロジェクトで、削除してよいことを確認してから試してください。

using UnityEngine;

public class Data_PlayerPrefs : MonoBehaviour
{
    void Start()
    {
        // 全データを削除
        PlayerPrefs.DeleteAll();
        PlayerPrefs.Save();
    }
}

実行してみると、データがすべて削除されましたね。(最初からあるデータは見せたらダメな気がして隠してます。)

PlayerPrefs.DeleteAllで保存データを削除した後のレジストリ

PlayerPrefsで保存されないときの確認項目

  • キー名と型は一致しているか:SetIntで保存した値は同じキーのGetIntで読み込みます。大文字・小文字やスペルも確認しましょう
  • 保存処理まで実行されているか:対象のGameObjectやスクリプトが有効か、Consoleにエラーがないかを確認します
  • 起動時に上書きしていないか:Startで初期値を毎回Setすると、前回の値が置き換わります
  • Saveのタイミングは適切か:強制終了直前の自動保存だけに頼らず、設定を確定した時点でSaveを呼びます
  • 保存先を取り違えていないか:Editorとビルドしたアプリは保存先が異なります。Company Name・Product Name・Bundle Identifierなどの変更にも注意してください
  • 別の処理で削除していないか:DeleteKeyやDeleteAll、アプリやブラウザーのデータ消去が実行されていないかを確認します

PlayerPrefsの注意点とJSONとの使い分け

  • 保存できるのは int, float, string のみ
  • 大量のデータや複雑な構造を管理するなら、JSONファイルなど別の保存方法も検討する
  • データは暗号化されず、改ざん対策にはならない。機密情報や課金・ランキングの正当性を保証したい情報は保存しない

PlayerPrefs全体が公式に非推奨とされているわけではありません。用途に合わせて選ぶことが大切です。JSONにするだけでも暗号化・改ざん対策にはならない点に注意しましょう。
セーブデータやアイテム情報をJSON形式で保存したい場合は、JsonUtilityでデータを保存・読み込みする方法を参考にしてください。

よくある質問

bool・配列・クラスはそのまま保存できる?

PlayerPrefsで直接保存できる型はint・float・stringです。boolなら0と1に変換して扱えます。以下はメソッド内で使う例です。

// boolを0/1にして保存する
bool isMuted = true;
PlayerPrefs.SetInt("IsMuted", isMuted ? 1 : 0);
PlayerPrefs.Save();

// 未保存ならfalseとして読み込む
bool loadedIsMuted = PlayerPrefs.GetInt("IsMuted", 0) == 1;

配列やクラスを扱いたい場合は、JSONなどへの変換が必要です。設定が増えてきたら、キーを増やし続けるより保存用クラスとファイルにまとめる方法も検討しましょう。

Playを停止してもデータは残る?

保存したPlayerPrefsは、通常はPlay Modeを停止しても残ります。もう一度Playして読み込めば、前回保存した値を確認できます。起動時に同じ値をSetする処理があると、保存が消えたように見えるため注意してください。

別の端末へ自動で引き継がれる?

PlayerPrefs自体は端末内の保存機能です。別端末への引き継ぎや、アカウント単位の保存を行いたい場合は、クラウド保存など別の仕組みが必要です。

まとめ

  • PlayerPrefs は「BGMやオプションデータ等の保存」に便利
  • int / float / string を保存・取得できる
  • Set・Get・Deleteを使い、設定を確定したタイミングでSaveする
  • 未保存なら初期値が返る。保存の有無を区別するときはHasKeyを使う
  • Editorとビルドの保存先の違い、機密情報を保存しないことに注意する