スポンサーリンク
エラー・トラブルシューティング

UnityでPlayerPrefsが保存されない原因まとめ|実機・WebGLで消える時の対処法

エラー・トラブルシューティング

UnityでPlayerPrefsを使っていると、「Editorではちゃんと保存されるのに、実機で動かすと値が戻る」「WebGLでページを閉じたら設定が消える」といった場面に出会うことがあります。

たとえば、音量設定を変更したはずなのに次回起動で初期値に戻ったり、ハイスコアを更新したのにアプリを開き直すと前のスコアに戻っていたりするケースです。見た目では保存できているように見えるので、ちょっとした罠ですね。

この問題は、単純に「コードが間違っている」とは限りません。PlayerPrefsには、値をセットする処理と、実際にストレージへ書き込む処理のタイミングがあります。さらに、実機やWebGLではEditorとは保存環境が違うため、同じコードでも結果が変わることがあります。

特に確認したいのは、次のようなポイントです。

  • PlayerPrefs.Save()を必要なタイミングで呼んでいるか
  • 保存直後にアプリを強制終了していないか
  • WebGLでブラウザ側の保存が完了する前にページを閉じていないか
  • 起動時に初期値で上書きしていないか
  • PlayerPrefsに向かない大きなデータを保存していないか

私の感覚では、最初はSave()忘れが多く、少し慣れてくると「起動時に自分で初期化していた」「WebGLだけ保存の仕組みが違った」というパターンでつまずきやすいです。犯人が一人とは限らないのが、デバッグのややこしいところです。

なお、PlayerPrefsは設定値やハイスコア、簡単なフラグ保存には便利です。ただし、インベントリや複雑な進行データ、大量のセーブデータを丸ごと任せる用途には向かない場合があります。

Editorでは動くのにビルド後だけ挙動が変わる場合は、PlayerPrefs以外にも実行環境の差が影響していることがあります。似た症状の切り分けには、コチラの記事も参考になります。




  1. まず確認すべき原因はこの5つ
  2. PlayerPrefs.Save()を呼んでいない
    1. ゲーム中は反映されるのに、再起動すると戻る
    2. 値の変更とディスクへの書き込みは別
    3. 重要な更新後にSaveを呼ぶ
    4. Saveの呼びすぎは避ける
  3. アプリの異常終了・強制終了で保存前に消えている
    1. クラッシュ後や強制終了後だけ値が戻る
    2. 終了時の自動保存に頼りすぎない
    3. セーブポイント方式で保存する
    4. 保存処理を1か所にまとめて呼び忘れを防ぐ
  4. WebGLでは保存の仕組みが違う
    1. ブラウザを閉じると値が残らない
    2. WebGLはIndexedDBに保存される
    3. 同期タイミングを意識する
    4. ブラウザや実行環境の影響を受ける
  5. キー名のミス・初期化処理・上書きで値が戻っている
    1. 保存した値ではなく初期値になる
    2. キー名の違いで別データとして扱われる
    3. 起動時に初期値で上書きしている
    4. Debug.Logで保存と読み込みを見える化する
    5. キー名は定数化して管理する
  6. PlayerPrefsに向かないデータを保存している
    1. PlayerPrefsに向いているデータ
    2. PlayerPrefsに向かないデータ
    3. 判断基準|この3つに当てはまったら別方式を検討
    4. より安全に保存したい場合の選択肢
  7. 3分で確認できる診断チェックリスト
  8. よくある誤解・注意点
    1. Setした瞬間に完全保存されるわけではない
    2. Editorで動けば実機でも同じとは限らない
    3. PlayerPrefsは暗号化された安全なセーブではない
    4. 大きなデータや複雑なデータ保存には向かない
  9. まとめ|PlayerPrefsが保存されない時は「Save・終了タイミング・環境差」から見る
  10. よくある質問(FAQ)
    1. 関連記事:

まず確認すべき原因はこの5つ

結論から言うと、PlayerPrefsが保存されない原因はある程度パターンが決まっています。ここを上から順に確認するだけで、ほとんどの場合は原因にたどり着けます。

優先度と発生頻度が高い順にまとめると、次の5つです。

  • ① PlayerPrefs.Save()を呼んでいない
    → 値は変更されているが、実際には保存されていない状態
  • ② 保存前にアプリが終了している
    → クラッシュ・強制終了・タブ閉じで保存処理が間に合っていない
  • ③ WebGLで同期が完了する前にページを閉じている
    → ブラウザ特有の保存仕様による問題
  • ④ キー名ミスや初期化処理で上書きしている
    → 実は保存されているが、読み込み側で消しているパターン
  • ⑤ PlayerPrefsに向かないデータを保存している
    → 容量・構造の問題で正常に扱えていない

ここで大事なのは、「症状から原因を逆算する」ことです。闇雲にコードをいじるより、パターンで切り分けた方が圧倒的に早く解決できます。

たとえば、次のように考えていきます。

  • 毎回必ず初期値に戻る → Save忘れ or 初期化処理ミス
  • たまに消える → 強制終了・保存タイミング問題
  • WebGLだけ消える → ブラウザ保存・同期問題
  • 一部の値だけおかしい → キー名や上書き処理

この段階で「どのパターンに近いか」をざっくり決めておくと、次の原因別の対処がスムーズになります。逆にここを飛ばすと、全部試すことになって時間を消耗しがちです。




PlayerPrefs.Save()を呼んでいない

PlayerPrefsが保存されない時に、まず確認したいのがPlayerPrefs.Save()です。

PlayerPrefs.SetInt()PlayerPrefs.SetString()を書いていると、「これで保存できた」と思いやすいのですが、ここには少し注意が必要です。SetIntなどは値をセットする処理であり、ストレージへ確実に書き込む処理とは分けて考えた方が安全です。

ゲーム中は反映されるのに、再起動すると戻る

たとえば、ゲーム中にハイスコア表示が更新されているのに、アプリを閉じて開き直すと古いスコアに戻ることがあります。

この場合、画面上では値が変わっているため「保存できているはず」と感じます。でも実際には、メモリ上の値が変わっているだけで、永続的な保存が完了していない可能性があります。ここがPlayerPrefsでよくある落とし穴です。

値の変更とディスクへの書き込みは別

PlayerPrefsは、アプリ終了時などに保存内容を書き込む仕組みがあります。ただし、クラッシュや強制終了などが起きると、その書き込み処理が実行されないことがあります。

そのため、重要な値を変更した直後は、明示的にPlayerPrefs.Save()を呼ぶのが基本です。

int highScore = 1000;

PlayerPrefs.SetInt("HighScore", highScore);
PlayerPrefs.Save();

このように、SetIntで値を設定したあとにSaveを呼ぶことで、保存タイミングを自分でコントロールできます。

重要な更新後にSaveを呼ぶ

PlayerPrefs.Save()を呼ぶタイミングは、「消えると困る値が確定した瞬間」と考えると判断しやすいです。

  • ハイスコアを更新した時
  • 音量や画質などの設定を変更して確定した時
  • ステージクリア時
  • チュートリアル完了時
  • ゲーム内通貨や解放フラグを更新した時

たとえば、設定画面で音量スライダーを動かすたびに保存するより、「決定」「閉じる」「戻る」などのタイミングで保存する方が扱いやすいです。

Saveの呼びすぎは避ける

PlayerPrefs.Save()は便利ですが、毎フレーム呼ぶような使い方はおすすめしません。保存処理はストレージへの書き込みを伴うため、タイミングによっては一瞬カクつく原因になることがあります。

特に、Update()の中で毎回呼んだり、ボタン連打のたびに保存したりすると、ゲームプレイ中の違和感につながるかもしれません。Saveは「重要な区切りで呼ぶ」くらいがちょうどいいです。

void SaveVolume(float volume)
{
    PlayerPrefs.SetFloat("Volume", volume);
    PlayerPrefs.Save();
}

保存処理をこのようにメソッド化しておくと、呼び忘れを防ぎやすくなります。あとから保存タイミングを見直す時も楽なので、地味ですがかなり助かります。




アプリの異常終了・強制終了で保存前に消えている

PlayerPrefs.Save()を書いているのに、なぜか「たまに保存されない」場合は、アプリの終了タイミングを疑ってみてください。

PlayerPrefsのトラブルは、毎回必ず失敗するとは限りません。普通に終了した時は保存されるのに、クラッシュした時やスマホでタスクキルした時だけ値が戻ることがあります。こういう気まぐれタイプ、デバッグ中はなかなか手強いです。

クラッシュ後や強制終了後だけ値が戻る

次のような症状がある場合は、保存処理が完了する前にアプリが終了している可能性があります。

  • ゲーム中に落ちた後、直前のスコアが保存されていない
  • スマホでアプリをタスクキルすると設定が戻る
  • ステージクリア直後に閉じると進行状況が戻る
  • ゲーム終了ボタンから閉じた時だけ保存される

特にモバイルでは、ユーザーがホームボタンを押したり、アプリをバックグラウンドに回したり、OS側の都合で終了されたりすることがあります。開発者が想定した「きれいな終了」だけが起きるとは限りません。

終了時の自動保存に頼りすぎない

PlayerPrefsは、アプリ終了時に変更内容が保存されることがあります。ただし、異常終了や強制終了では、その処理が最後まで実行されない場合があります。

そのため、「最後にまとめて保存すればいい」という設計にしていると、クラッシュやタスクキルのタイミングで最新データが抜け落ちることがあります。

たとえば、ステージをクリアした時点では内部的にstageClear = trueになっていても、保存をゲーム終了時にまとめて行う設計だと、終了前にアプリが落ちた時に進行状況が戻ってしまいます。

セーブポイント方式で保存する

対策としては、「重要な出来事が確定した時点で保存する」形にするのがおすすめです。ゲーム終了時に頼るより、データが変わった節目で保存した方が安全です。

  • ステージクリア時
  • チェックポイント到達時
  • 報酬を受け取った時
  • 設定画面を閉じた時
  • チュートリアル完了時
public void ClearStage(int stageNumber)
{
    PlayerPrefs.SetInt("ClearedStage", stageNumber);
    PlayerPrefs.Save();
}

このように、進行状況が確定したタイミングで保存しておくと、突然アプリが終了しても被害を小さくできます。

保存処理を1か所にまとめて呼び忘れを防ぐ

保存処理がいろいろなスクリプトに散らばっていると、「ここではSaveしているけど、こっちでは忘れていた」という状態になりやすいです。

小さなゲームなら直接書いても問題ありませんが、少し規模が大きくなってきたら、保存用のメソッドを用意しておくと管理しやすくなります。

public static class SaveManager
{
    public static void SaveHighScore(int score)
    {
        PlayerPrefs.SetInt("HighScore", score);
        PlayerPrefs.Save();
    }

    public static void SaveVolume(float volume)
    {
        PlayerPrefs.SetFloat("Volume", volume);
        PlayerPrefs.Save();
    }
}

「保存はこのメソッドを通す」と決めておくと、あとから保存タイミングを見直す時も迷いにくくなります。

セーブ処理は、単に値を書き込むだけでなく「どのタイミングなら失っても困らないか」を考えるのが大切です。より安全な保存設計まで踏み込みたい場合は、コチラの記事も参考になります。




WebGLでは保存の仕組みが違う

「PCビルドでは問題ないのに、WebGLだけ保存されない」という場合は、ほぼ確実に保存の仕組みの違いが原因です。

WebGLはローカルアプリとは違い、ブラウザ上で動くため、データの保存方法もブラウザ依存になります。ここを知らないと、同じコードなのに動かない理由が分からずハマりやすいです。

ブラウザを閉じると値が残らない

よくある症状としては、次のようなものがあります。

  • ページをリロードすると設定が初期化される
  • タブを閉じるとハイスコアが消える
  • 同じURLなのに別のブラウザでは保存されない

Editorやスタンドアロンでは問題ないのに、WebGLだけ不安定になるのが特徴です。

WebGLはIndexedDBに保存される

WebGLでは、PlayerPrefsのデータはブラウザのIndexedDBという仕組みに保存されます。これはローカルストレージの一種ですが、書き込みが非同期(すぐに完了しない)という特徴があります。

つまり、PlayerPrefs.Save()を呼んでも、その瞬間に完全に保存されるとは限らず、少し遅れて実際の保存処理が行われる場合があります。

この状態でタブを閉じたりページ遷移すると、保存処理が途中で止まり、結果的にデータが残らないことがあります。

同期タイミングを意識する

対策としては、「保存した直後にすぐ閉じない」ことがシンプルですが重要です。

  • セーブ直後にページをリロードしない
  • 重要な保存後は少し余裕を持たせる
  • ユーザー操作で即終了しないようUI設計を工夫する

また、WebGLテンプレートの設定によっては、保存の同期挙動が変わることがあります。生成されるindex.html内の設定(例:自動同期関連のオプション)を確認するのも一つの手です。ただし、このあたりはUnityのバージョンやテンプレートによって差があるため、環境ごとに挙動をチェックする必要があります。

ブラウザや実行環境の影響を受ける

さらに、WebGLはブラウザの制限も受けます。次のようなケースでは、正常に保存できない可能性があります。

  • プライベートブラウズ(シークレットモード)
  • 一部ブラウザでの制限(特にSafariなど)
  • iframe内での実行
  • ブラウザのストレージ制限に達している場合

このあたりはユーザー環境に依存するため、「特定の環境だけ保存されない」という現象も起こり得ます。

判断のコツとしては、「WebGLだけ挙動がおかしいなら、まずブラウザ保存を疑う」です。コードではなく環境側に原因があるケースも多いので、PCビルドとWebGLで切り分けて確認するのがおすすめです。




キー名のミス・初期化処理・上書きで値が戻っている

PlayerPrefs.Save()を呼んでいて、アプリの終了タイミングにも問題がなさそうなのに値が戻る場合は、「保存できていない」のではなく「保存後に別の処理で上書きしている」可能性があります。

このパターンは意外と多いです。保存処理だけ見ていると正しく見えるので、犯人がコードの別の場所に隠れているんですね。まるで探偵パートです。

保存した値ではなく初期値になる

たとえば、次のような症状がある場合は、キー名や初期化処理を疑ってみてください。

  • GetInt("HighScore", 0)が毎回0になる
  • 音量設定を変更しても、起動すると初期音量に戻る
  • チュートリアル完了フラグが毎回未完了になる
  • 一部の値だけ保存されない

特に「たまに消える」ではなく「毎回必ず同じ値に戻る」場合は、保存タイミングよりも、読み込み時や起動時の上書きを先に見た方が早いです。

キー名の違いで別データとして扱われる

PlayerPrefsは、キー名を使って値を保存します。つまり、保存時と読み込み時のキー名が少しでも違うと、別のデータとして扱われます。

PlayerPrefs.SetInt("HighScore", 1000);
PlayerPrefs.Save();

int score = PlayerPrefs.GetInt("highScore", 0);

この例では、保存時は"HighScore"、読み込み時は"highScore"になっています。大文字と小文字が違うため、同じキーとして扱われません。

こうなると、保存したはずなのにGetIntの初期値である0が返ってきます。コード上はエラーにならないので、気づきにくいミスです。

起動時に初期値で上書きしている

もう一つよくあるのが、Awake()Start()で毎回初期値を保存してしまうケースです。

void Start()
{
    PlayerPrefs.SetInt("HighScore", 0);
    PlayerPrefs.Save();
}

このコードがあると、ゲームを起動するたびにハイスコアが0で上書きされます。保存処理は正常に動いているのに、自分で初期化してしまっている状態です。

初期値を入れたい場合は、すでに保存済みのデータがあるかどうかを確認してから実行します。

void Start()
{
    if (!PlayerPrefs.HasKey("HighScore"))
    {
        PlayerPrefs.SetInt("HighScore", 0);
        PlayerPrefs.Save();
    }
}

HasKeyを使うと、そのキーがすでに保存されているか確認できます。初回起動だけ初期値を入れたい時に便利です。

Debug.Logで保存と読み込みを見える化する

値が戻る原因を探す時は、保存直後と読み込み直後にログを出すとかなり分かりやすくなります。

PlayerPrefs.SetInt("HighScore", 1000);
PlayerPrefs.Save();

Debug.Log("保存直後: " + PlayerPrefs.GetInt("HighScore", 0));
int loadedScore = PlayerPrefs.GetInt("HighScore", 0);
Debug.Log("読み込み時: " + loadedScore);

保存直後は正しいのに、起動後だけ値が変わっているなら、起動時のどこかで上書きされている可能性が高いです。

ログを使った原因特定に慣れておくと、PlayerPrefs以外の不具合にも対応しやすくなります。デバッグの基本を整理したい場合は、コチラの記事も役立ちます。

キー名は定数化して管理する

キー名のミスを防ぐには、文字列をあちこちに直接書かないことが大切です。よく使うキーは、定数としてまとめておくと安全です。

public static class PrefsKey
{
    public const string HighScore = "HighScore";
    public const string Volume = "Volume";
}
PlayerPrefs.SetInt(PrefsKey.HighScore, 1000);
PlayerPrefs.Save();

int score = PlayerPrefs.GetInt(PrefsKey.HighScore, 0);

この形にしておくと、スペル違いや大文字小文字のミスを減らせます。小さな工夫ですが、後から効いてくるタイプの対策です。




PlayerPrefsに向かないデータを保存している

ここまでの対策を試しても問題が解決しない場合、「そもそもPlayerPrefsで扱うべきではないデータを保存している」可能性も考えてみてください。

PlayerPrefsはとても便利ですが、あくまで軽い設定データ向けの仕組みです。用途を間違えると、保存できない・壊れる・扱いづらいといった問題につながります。

PlayerPrefsに向いているデータ

まずは、問題なく使える代表的なデータです。

  • 音量や画質などの設定値
  • 言語設定
  • ハイスコア
  • チュートリアル完了フラグ
  • ON/OFFの簡単な状態管理

ポイントは、「シンプルで小さいデータ」です。数値や短い文字列で表現できるものは、PlayerPrefsと相性が良いです。

PlayerPrefsに向かないデータ

逆に、次のようなデータはPlayerPrefsだけで扱うとトラブルの原因になりやすいです。

  • インベントリ(所持アイテム一覧)
  • セーブスロット管理
  • 複雑な進行状況(クエスト・分岐など)
  • 大量のデータ(長いJSON文字列など)
  • 改ざんされると困る重要データ

特にWebGLでは保存容量に制限があるため、データが大きくなるほど保存に失敗しやすくなります。また、構造が複雑なデータを無理やり文字列に詰め込むと、後からの管理も大変になります。

判断基準|この3つに当てはまったら別方式を検討

迷った時は、次の基準で判断すると分かりやすいです。

  • 消えたら困るか? → 困るならPlayerPrefs以外も検討
  • データ量は多いか? → 多いなら別方式
  • 構造は複雑か? → 複雑ならJSONや専用ツール

このどれかに当てはまる場合は、PlayerPrefsだけに頼らない設計にした方が安全です。

より安全に保存したい場合の選択肢

少し本格的なセーブ処理を作りたい場合は、次のような方法があります。

  • JSON形式でファイル保存する
  • セーブ専用アセットを使う
  • 独自のセーブ管理クラスを作る

特にアセットを使うと、暗号化や複雑なデータ構造にも対応しやすくなります。

Easy Save
✅アセットストアでチェックする

Odin Serializer
✅アセットストアでチェックする

「PlayerPrefsでは足りないな」と感じた段階でこういった選択肢に移行すると、あとから作り直す手間を減らせます。

また、JSONを使った保存方法については、コチラの記事でも詳しく解説されています。

PlayerPrefsは便利な道具ですが、万能ではありません。「軽い設定だけ任せる」と割り切ると、トラブルもかなり減ります。




3分で確認できる診断チェックリスト

ここまで読んでも原因がはっきりしない場合は、上から順にチェックしていくのが一番早いです。順番通りに見ていけば、初心者でも迷わず原因を絞り込めます。

実際に私も、原因が分からない時はこのチェックを上から潰していくことが多いです。余計な遠回りをしなくなるので、かなりおすすめです。

  • ① SetのあとにSaveを呼んでいるか
    PlayerPrefs.SetInt()だけで終わっていないか確認
  • ② 保存直後にアプリを閉じていないか
    → 強制終了・タスクキル・クラッシュ直前の操作を確認
  • ③ 起動時に初期値を上書きしていないか
    Start()Awake()で毎回Setしていないか
  • ④ キー名が一致しているか
    → 大文字小文字・スペルミス・コピペミスを確認
  • ⑤ HasKeyで保存されているか確認したか
    → 保存自体ができているか切り分ける
  • ⑥ Editor以外でも同じ挙動か
    → 実機・WebGLで再現するかチェック
  • ⑦ 保存しているデータ量が大きすぎないか
    → 長い文字列や大量データを入れていないか
  • ⑧ WebGLならブラウザ環境を確認したか
    → リロード直後・シークレットモード・別ブラウザで検証

チェックする時のコツは、「全部一気に見る」のではなく、1つずつ確実に切り分けることです。

たとえば、まずはSave()を入れてログで確認する → 次に起動時の処理を見る → 最後にWebGL環境を疑う、といった順番で進めると混乱しにくいです。

また、症状ごとに目安を持っておくと判断しやすくなります。

  • 毎回必ず消える → Save忘れ or 初期化ミスの可能性が高い
  • たまに消える → 終了タイミングやクラッシュを疑う
  • WebGLだけ消える → ブラウザ保存・同期問題
  • 一部だけおかしい → キー名・上書き処理

このチェックリストを一通り確認すれば、「どこが怪しいか」はかなり絞り込めるはずです。あとは該当する原因の対処をピンポイントで直していきましょう。




よくある誤解・注意点

PlayerPrefsは使い方がシンプルなので、最初は「とりあえず保存できる便利な箱」のように見えます。ただ、実際にはいくつか勘違いしやすいポイントがあります。

ここを押さえておくと、「コードは合っているのに保存されない気がする」というモヤモヤを減らせます。

Setした瞬間に完全保存されるわけではない

PlayerPrefs.SetInt()PlayerPrefs.SetString()を呼ぶと、値はPlayerPrefsに設定されます。

ただし、「値を設定すること」と「ストレージに確実に書き込むこと」は分けて考えた方が安全です。

PlayerPrefs.SetInt("HighScore", 1000);

このコードだけでも動作中は値を取り出せますが、保存タイミングによっては再起動後に残らない可能性があります。重要な値なら、次のようにSave()まで呼んでおくのがおすすめです。

PlayerPrefs.SetInt("HighScore", 1000);
PlayerPrefs.Save();

特に、スコア更新や設定変更など「消えると困る値」は、変更したタイミングで保存まで済ませておくと安心です。

Editorで動けば実機でも同じとは限らない

Unity Editor上で問題なく動いていても、実機やWebGLで同じように動くとは限りません。

Editorでは正常に保存できているように見えても、スマホではアプリの終了タイミングが違ったり、WebGLではブラウザの保存領域を使ったりします。

特に次のような環境では、Editorだけの確認で終わらせない方が安全です。

  • AndroidやiOSなどのスマホ実機
  • WebGLビルド
  • ブラウザ上で公開するゲーム
  • ユーザーが途中で閉じる可能性が高いゲーム

「Editorでは動いたから完成!」と言いたくなる気持ちはとても分かります。ですが、セーブ周りだけは実機確認までしておくと、あとで冷や汗をかきにくくなります。

PlayerPrefsは暗号化された安全なセーブではない

PlayerPrefsは、手軽に値を保存できる仕組みですが、重要なデータを安全に守るための仕組みではありません。

保存場所はプラットフォームごとに違いますが、基本的にはユーザー側の端末にデータが残ります。そのため、環境によっては中身を見られたり、書き換えられたりする可能性があります。

たとえば、次のようなデータはPlayerPrefsだけに任せると少し不安です。

  • 課金アイテムの所持状態
  • ゲーム内通貨
  • ランキングに影響するスコア
  • 改ざんされると困る進行データ

個人制作の小さなゲームであれば許容できることもありますが、ランキングや課金要素が絡む場合は、サーバー管理や改ざん対策も考えた方が安全です。

大きなデータや複雑なデータ保存には向かない

PlayerPrefsは、数値・文字列・簡単なフラグを保存するには便利です。一方で、複雑なデータを無理やり入れようとすると、管理が難しくなります。

たとえば、インベントリの中身、複数セーブスロット、クエスト進行、装備状態などを全部PlayerPrefsで管理しようとすると、キーが大量に増えて見通しが悪くなります。

PlayerPrefs.SetInt("Item_001_Count", 3);
PlayerPrefs.SetInt("Item_002_Count", 1);
PlayerPrefs.SetInt("Quest_005_Clear", 1);
PlayerPrefs.SetString("PlayerWeapon", "IronSword");

少量なら問題ありませんが、増えてくると「どのキーが何を表しているのか」が分かりにくくなります。未来の自分が泣くタイプのコードです。

セーブスロットやJSON保存、Easy Saveのような専用ツールとの違いを比較したい場合は、コチラの記事も参考になります。

PlayerPrefsは「軽い設定を保存する道具」として使うと、とても頼れる存在です。逆に、ゲーム全体のセーブシステムを全部任せようとすると、途中からつらくなりやすいので注意しましょう。




まとめ|PlayerPrefsが保存されない時は「Save・終了タイミング・環境差」から見る

PlayerPrefsが保存されない問題は、原因がバラバラに見えても、ほとんどは次の3つに集約されます。

  • Saveの呼び忘れ
  • 終了タイミングの問題(強制終了・クラッシュ)
  • 実行環境の違い(特にWebGL)

まずはこの順番で疑うだけでも、かなりの確率で原因にたどり着けます。

さらに細かく切り分けるなら、次のように考えると判断しやすいです。

  • 毎回必ず消える → Save忘れ・初期化処理の可能性が高い
  • たまに消える → 異常終了や保存タイミングの問題
  • WebGLだけ消える → ブラウザ保存・同期の問題
  • 一部だけおかしい → キー名・上書き処理

この「症状 → 原因のあたりをつける」流れを意識すると、デバッグのスピードがかなり変わります。

再発防止のポイントとしては、次の3つを意識しておくと安心です。

  • 重要なデータはイベント単位(クリア・設定確定など)で保存する
  • 保存処理を1か所にまとめて管理する
  • Editorだけでなく実機・WebGLでも必ず確認する

私の経験上、最初はSave()の呼び忘れでつまずくことが多いですが、慣れてくると「起動時の初期化」「WebGLの挙動差」でハマるケースが増えてきます。ここを意識しておくだけでも、かなりトラブルは減らせます。

PlayerPrefsはとても便利な仕組みですが、「何でも保存できる万能ツール」ではありません。用途を絞って使うことで、シンプルで扱いやすいセーブ処理になります。

もし「セーブ機能をしっかり作りたい」と感じたら、その時が設計を一段階上げるタイミングです。今回のポイントを土台にして、より安全で柔軟な保存方法に進んでいきましょう。


よくある質問(FAQ)

Q
PlayerPrefs.Save()は毎回呼んだ方がいいですか?
A

結論から言うと、「毎回」ではなく「重要なタイミングで」呼ぶのがおすすめです。

たとえば、ハイスコア更新・設定変更の確定・ステージクリアなど、「ここで消えたら困る」というポイントで呼びます。

逆に、毎フレームやボタン連打のたびにSave()を呼ぶと、書き込み負荷によって一瞬のカクつきが発生する可能性があります。

迷った時は、「このタイミングでアプリが落ちても困らないか?」で判断すると決めやすいです。

Q
PlayerPrefsはスマホアプリでも使って大丈夫ですか?
A

設定値やハイスコアのようなシンプルなデータであれば、スマホアプリでも問題なく使えます。

ただし、モバイル環境では次の点に注意が必要です。

  • ユーザーがタスクキルする可能性がある
  • バックグラウンド遷移で終了タイミングが不安定
  • クラッシュ時に保存処理が間に合わない場合がある

そのため、終了時にまとめて保存するのではなく、進行が確定したタイミングでこまめに保存する設計にしておくと安心です。

Q
WebGLで保存されない時は何を最初に確認すべきですか?
A

まずは次の3つを順番に確認すると切り分けしやすいです。

  • PlayerPrefs.Save()を呼んでいるか
  • 保存直後にページを閉じたりリロードしていないか
  • ブラウザ環境(シークレットモード・別ブラウザ)で挙動が変わるか

それでも解決しない場合は、WebGLテンプレートの設定やブラウザの保存制限(IndexedDBの利用可否)も確認してみてください。

WebGLはブラウザに依存する部分が大きいため、「特定の環境だけ保存されない」というケースもあり得ます。PCビルドと比較しながら確認すると原因を切り分けやすくなります。

※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。

※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。

スポンサーリンク