はじめに
Unityでゲームを作り始めた頃は、セーブデータといえば PlayerPrefs で十分だった、という方は多いと思います。
数値を保存して、ロードして、動いたらOK。最初はそれで問題ありません。
でも、ゲーム制作が少し進んでくると、こんな不安が出てきませんか?
- セーブする項目が増えて、どこで何を保存しているか分からない
- PlayerPrefsのキー名が増殖して管理がつらい
- あとから仕様変更したら、セーブデータが壊れそうで怖い
このあたりで多くの人が気になり始めるのが、JSON形式でのセーブ/ロードです。
JSONは「なんとなく便利そう」「PlayerPrefsより上位互換っぽい」というイメージを持たれがちですが、
実際には 設計を意識せずに使うと、普通に破綻します。
この記事では、単に「JSONで保存する方法」を紹介するのではなく、
- なぜJSONが選択肢になるのか
- PlayerPrefsやBinaryとの違いは何か
- 実務で壊れにくいセーブデータ構造とは何か
- 中規模ゲームでも使える最適化・保守の考え方
といった 設計視点 まで踏み込んで解説していきます。
「とりあえず動くセーブ」から、
「最後まで作り切れるセーブ設計」へ進みたい方に向けた内容です。
結論:UnityのJSONセーブは「設計前提」で使うと強い
先に結論からお伝えします。
UnityにおけるJSONセーブは、
「PlayerPrefsの代わり」や「とりあえず使う保存方法」ではありません。
JSONは、セーブデータの構造をきちんと設計する前提で使うことで、はじめて本領を発揮します。
逆に言うと、設計を考えずに導入すると、
- データ構造がぐちゃぐちゃになる
- 後から仕様変更に耐えられない
- 「PlayerPrefs地獄」と同じ状態がJSONで再発する
ということが普通に起こります。
ここで一度、保存方式の立ち位置を整理しておきましょう。
- 小規模・設定値のみ:PlayerPrefs
- 小〜中規模・構造化されたデータ:JSON
- 改ざん耐性・大規模:Binary / サーバー保存
JSONはちょうど真ん中に位置する、
「個人開発で最も現実的に使われやすい選択肢」です。
特に、
- プレイヤー成長要素がある
- 所持アイテムや進行フラグが増えてきた
- セーブデータを一つのまとまりとして扱いたい
こういったゲームでは、JSONのメリットがはっきり効いてきます。
このあとの章では、
- なぜPlayerPrefsだけでは限界が来るのか
- JSONが向いているケース・向いていないケース
- 実務で破綻しにくいデータ構造の考え方
を順番に整理しながら、
「JSONを使うべきかどうか判断できる状態」を目指していきます。
なぜPlayerPrefsだけでは限界が来るのか
Unityでセーブ処理を学び始めたとき、PlayerPrefs はとても便利に感じます。
コードも短く、すぐ動いて、考えることが少ない。初心者にとっては理想的です。
ただし、この「手軽さ」は、ゲームが成長するにつれてそのまま足かせになります。
PlayerPrefsのメリットと限界
まずは冷静に、PlayerPrefsの特徴を整理してみましょう。
- 保存できる型は int / float / string のみ
- キーと値のペアで管理する方式
- 手軽だが、構造を持てない
設定画面の音量やオプション程度であれば、これはまったく問題ありません。
むしろ最適解です。
問題が出てくるのは、次のようなケースです。
- プレイヤーのステータスが増えてきた
- 所持アイテムをリストで管理したくなった
- 進行状況やフラグが複雑になってきた
こうなると、PlayerPrefsでは「構造」を表現できないことが一気に効いてきます。
よくあるPlayerPrefs地獄の例
実際の個人開発でよく見るのが、こんな状態です。
- PlayerPrefsのキー名が無限に増える
- どのキーが何に使われているか分からない
- 削除していいキーか判断できない
さらに厄介なのが、仕様変更です。
たとえば、
- ステータス構成を変更した
- アイテムの持ち方を変えた
- フラグ管理を整理した
こうした変更を行うと、
既存のセーブデータとの整合性が一気に崩れます。
結果として、
- 古いキーを残したままにする
- 読み込み時に分岐が増える
- セーブ処理がどんどん複雑化する
という悪循環に陥りがちです。
問題は「保存方法」ではなく「設計」
ここで大事なのは、
PlayerPrefsが悪いわけではないという点です。
本質的な問題は、
「セーブデータをどういう構造で管理したいか」を考えずに使っていること
にあります。
PlayerPrefsは「構造を持たない前提」の仕組みです。
一方で、ゲームのセーブデータは時間とともに必ず構造化されていくものです。
このギャップが大きくなったとき、
自然と次の選択肢として浮上するのが JSON形式のセーブ です。

次の章では、
なぜJSONがこの問題に対して有効なのかを整理していきます。
JSONを使う理由と、向いているケース
PlayerPrefsの限界が見えてきたとき、次の選択肢としてよく名前が挙がるのが JSON形式でのセーブです。
ただし、ここで一つはっきりさせておきたいことがあります。
JSONは「万能だから使うもの」ではありません。
PlayerPrefsの問題点と噛み合ったときに、はじめて意味を持ちます。
JSONが持つ強み
JSONがセーブデータとして選ばれる最大の理由は、構造を持てることです。
- オブジェクトをそのまま保存できる
- 配列・リストを自然に扱える
- ネスト(階層構造)でデータをまとめられる
たとえば、
- プレイヤーステータス
- 所持アイテム一覧
- ゲーム進行フラグ
こうした情報を1つのまとまりとして扱えるのが、JSONの大きな強みです。
また、JSONはテキスト形式なので、
- 中身を目で確認できる
- デバッグしやすい
- 保存内容を把握しやすい
といった点も、個人開発ではかなり助けになります。
JSONは「シリアライズ設計」の延長線にある
JSONセーブを正しく理解するためには、
Unityのシリアライズの考え方を避けて通れません。
Unityでは、[Serializable] が付いたクラスを 「保存・復元できるデータの単位」として扱います。
JSONは、このシリアライズされたデータをテキストとして書き出したものにすぎません。
つまり、
JSONが優秀なのではなく、設計されたデータ構造が優秀なので扱いやすい
という順番です。
シリアライズの前提や制約をきちんと理解しておきたい方は、 以下の記事もあわせて読むと理解が深まります。
JSONが向いているゲーム規模
では、どんなケースでJSONが向いているのでしょうか。
目安としては、次のような条件がそろったときです。
- PlayerPrefsでは管理しきれないと感じ始めた
- セーブデータに明確な構造がある
- 小〜中規模で、ローカル保存が前提
逆に、
- 改ざん耐性が最重要
- セーブデータが巨大
- オンライン前提
こうした場合は、Binary形式やサーバー保存の方が適しています。
JSONはあくまで、
「個人開発で最後まで作り切るための、現実的な落としどころ」
として考えるのがちょうどいい立ち位置です。

次は、PlayerPrefs・Binary・JSONを並べて、 保存方式の違いをもう少し具体的に比較していきます。
PlayerPrefs / Binary / JSON の保存方式比較
ここまでで、PlayerPrefsとJSONの立ち位置はある程度見えてきたと思います。
この章では、よく比較される PlayerPrefs / Binary / JSON の3つを並べて、 もう一度整理しておきましょう。
大事なのは、
「どれが最強か」ではなく「どれが今のゲームに合っているか」です。
保存方式ごとの特徴
| 方式 | 特徴 | 向いている用途 |
|---|---|---|
| PlayerPrefs | 手軽・実装が簡単 構造を持てない | 音量設定 オプション設定 |
| Binary | 改ざんされにくい 人間が読めない | チート対策が必要なデータ 大規模セーブ |
| JSON | 構造化できる 可読性が高い | プレイヤー進行データ 小〜中規模ゲーム |
この表から分かる通り、JSONはちょうど中間に位置します。
「JSONを使えば全部解決」ではない
ここでよくある誤解があります。
JSONにすれば、セーブの悩みがすべて解決する
――これは残念ながら間違いです。
JSONはあくまで、
- 構造を表現できる
- 一括で保存・ロードできる
という器を提供してくれるだけです。
中身の設計が整理されていなければ、
- 巨大なJSONファイルができる
- どこに何が入っているか分からない
- 結局、変更に弱くなる
といった問題は普通に起こります。
実務では「併用」が前提になることも多い
実際の開発では、
1つの保存方式だけで完結させないケースも多いです。
- 設定値:PlayerPrefs
- 進行データ:JSON
- 重要データ:Binary or サーバー
このように役割を分けることで、
- 実装がシンプルになる
- 壊れやすい部分を限定できる
- 将来の拡張もしやすい
というメリットがあります。

次の章では、
JSONを使う前提で、実務で破綻しにくいデータ構造の設計について、 もう一段踏み込んで解説していきます。
実務で破綻しにくいJSONデータ構造の設計
JSONセーブで一番つまずきやすいのが、
「どういうデータ構造にすればいいのか分からない」という点です。
実は、JSONそのものよりも大事なのは、
セーブ対象のデータをどう整理するかという設計部分だったりします。
セーブ用のデータは1つのクラスに集約する
まず基本としておすすめなのが、
セーブ専用のデータクラスを1つ用意することです。
たとえば、SaveData のようなクラスを作り、
- プレイヤーステータス
- 所持アイテム
- 進行状況
などをすべてこのクラスの中にまとめます。
ここで重要なのは、
- MonoBehaviourを継承しない
[Serializable]を付ける- 「保存したいデータだけ」を入れる
という3点です。
ゲームロジック用のクラスと、
セーブ用のデータクラスを分けることで、
- 保存内容が把握しやすくなる
- 仕様変更の影響範囲が限定される
といったメリットがあります。
データの責務を意識して階層化する
すべての変数をフラットに並べると、
JSONはすぐに読みづらくなります。
そこで、
- プレイヤー情報
- インベントリ情報
- システム設定
といった役割ごとにクラスを分けてネストしていきます。
こうすることで、
- JSONの構造が直感的になる
- 特定データの追加・削除がしやすい
という状態を作れます。
ScriptableObjectとJSONの役割を混同しない
ここでよくある勘違いが、
「ScriptableObjectをそのまま保存したい」という発想です。
ScriptableObjectは、
- エディタ上でデータを管理する
- 実行中の参照データとして使う
のに向いています。
一方で、JSONは永続化(保存)が役割です。
そのため実務では、
- 実行中:ScriptableObjectで管理
- 保存時:必要な値だけSaveDataにコピー
という形に分けるのが安定します。
この考え方については、以下の記事でも詳しく解説しています。
「あとから増える」前提で設計する
セーブデータは、ほぼ確実に後から項目が増えます。
だからこそ、
- 1つの巨大クラスにしすぎない
- 役割単位で分割する
- 将来追加されそうな余地を残す
といった視点がとても重要です。

次の章では、
この設計を前提にしたJSONセーブ/ロードの基本的な実装フローを整理していきます。
JSONセーブ/ロードの基本実装フロー
ここまでで、
JSONセーブは「設計が8割」という話をしてきました。
この章では、その設計を前提にしたうえで、
UnityでのJSONセーブ/ロードの基本的な流れを整理します。
細かいコードの書き方よりも、
「どういう順番で、何をしているのか」を理解することを目的に進めます。
1. 保存先パスを取得する
まず必ず使うのが、Application.persistentDataPath です。
これは、
- Windows
- macOS
- iOS / Android
といった各プラットフォームで、
「セーブデータを書き込んでよい場所」をUnityが自動で返してくれます。
保存パスを自前で決めてしまうと、
プラットフォームごとの違いでトラブルになりがちなので、 ここは素直にUnityに任せるのが安全です。
2. セーブ処理(シリアライズ)
セーブの流れはとてもシンプルです。
- SaveDataクラスのインスタンスを用意する
JsonUtility.ToJsonでJSON文字列に変換する- ファイルとして書き込む
ここで大事なのは、
- セーブ対象はSaveDataに集約されている
- ゲームロジック側は保存処理を意識しない
という設計になっていることです。
この状態を作れていれば、
セーブ処理そのものはほぼ定型作業になります。
3. ロード処理(デシリアライズ)
ロード時も考え方は同じです。
- ファイルが存在するか確認する
- JSON文字列を読み込む
JsonUtility.FromJsonでSaveDataに復元する
ここで注意したいのは、
「ロードできなかった場合の初期化」です。
たとえば、
- 初回起動
- セーブデータ削除後
などでは、ファイルが存在しません。
その場合は、
- デフォルト値でSaveDataを生成する
- ゲーム開始に支障が出ない状態を作る
という分岐を必ず用意しておきましょう。
4. ロード後に「反映」する工程を忘れない
JSONからSaveDataを復元できたとしても、
それだけではゲームは元に戻りません。
ロード後には、
- プレイヤーステータスへ反映
- インベントリの再構築
- 進行状況の復元
といった反映処理が必ず必要になります。
この反映処理をどこで行うか、
どのクラスが責任を持つかも、設計段階で決めておくと混乱しません。

次の章では、
この基本フローを前提にした「中規模ゲーム向けの最適化ポイント」について解説していきます。
中規模ゲーム向け最適化ポイント
JSONセーブ/ロードは、基本的な仕組み自体はシンプルです。
ただし、ゲームの規模が少し大きくなってくると、 「動くけど不安定」「たまに壊れる」といった問題が出やすくなります。
ここでは、
小〜中規模ゲームでも破綻しにくくするための実践的な最適化ポイントを整理します。
セーブファイルを1つにまとめすぎない
最初にやりがちなのが、
すべてのデータを1つの巨大なJSONファイルにまとめることです。
これは小規模なうちは問題ありませんが、
- データ量が増える
- 保存頻度が上がる
- 一部だけリセットしたくなる
といった状況になると、扱いづらさが一気に表面化します。
そこでおすすめなのが、役割ごとにファイルを分割する考え方です。
- system.json(設定・オプション)
- progress.json(進行状況)
- inventory.json(所持アイテム)
こうしておくと、
- 特定データだけ初期化できる
- 読み書きの範囲を限定できる
- 不具合の切り分けがしやすい
といったメリットがあります。
保存タイミングを明確に設計する
JSONの書き込みは、思っている以上にコストが高い処理です。
そのため、
- 毎フレーム保存する
- 状態が少し変わるたびに保存する
といった実装は避けるべきです。
おすすめなのは、
- チェックポイント到達時
- 明示的なセーブ操作時
OnApplicationQuit時
など、保存タイミングを限定する設計です。
これだけでも、パフォーマンス面・安定性の両方がかなり改善します。
上書き保存の危険性を理解しておく
JSONセーブで見落とされがちなのが、
上書き保存によるデータ破損リスクです。
保存中に、
- アプリが強制終了した
- 端末の電源が落ちた
といったことが起こると、
セーブデータが完全に壊れる可能性があります。
この問題と対策については、以下の記事で詳しく解説しています。
最低限でも、
- 一時ファイルに書き込む
- 正常終了後に差し替える
といった工夫を入れておくと、安心感が大きく変わります。
「あとから壊れない」視点を持つ
セーブデータは、
今だけでなく「未来の自分」が触るものです。
最適化というとパフォーマンスに目が向きがちですが、
- データ構造が分かりやすい
- 影響範囲が限定されている
- 変更点を追いやすい
といった保守性も同じくらい重要です。

次の章では、
JSONセーブの弱点と、その現実的な対策について整理していきます。
JSONの弱点と現実的な対策
ここまで読むと、JSONセーブはかなり便利に感じると思います。
ただし、当然ながら弱点もはっきり存在します。
この章では、
JSONを採用する前に必ず知っておきたいデメリットと、 実務でよく使われる現実的な対策を整理します。
JSONは改ざんされやすい
JSONはテキスト形式です。
つまり、極端な話をすると、
- メモ帳で開ける
- 数値を書き換えられる
という状態になります。
オフラインゲームの場合、
- レベルを最大にする
- 所持金を増やす
といった改ざんは、
技術的には簡単に可能です。
ここで大事なのは、
「改ざんを完全に防げるか」ではなく「どこまで許容するか」です。
JSONの弱点は「設計」である程度カバーできる
多くの個人開発・小規模ゲームでは、
- 多少の改ざんは許容する
- 深刻な不正行為は想定しない
という前提で設計されることがほとんどです。
その場合、
- 値をそのまま保存しない
- 計算結果だけを保存する
- 重要なフラグは分離する
といった工夫だけでも、 実害の出にくい構造を作ることができます。
軽い難読化・Binary併用という選択肢
もう少し対策したい場合は、
- Base64エンコード
- 簡単な暗号化
といった軽い難読化を挟むだけでも、 「誰でも簡単に改ざんできる」状態は防げます。
また、
- 進行データはJSON
- 重要データだけBinary
という併用設計も、実務ではよく使われます。
アップデート時に壊れにくいのはJSONの強み
一方で、JSONにはBinaryより優れている点もあります。
それが、アップデート耐性です。
変数が増えたり、構造が少し変わった場合でも、
- 新しい項目はデフォルト値で補完
- 古い項目は無視
といった対応がしやすく、 致命的な破損になりにくいという特徴があります。
アップデートに強いセーブ設計については、 以下の記事でより詳しく解説しています。
JSONは「完璧な保存方式」ではありません。
ですが、
弱点を理解したうえで使えば、非常にバランスの取れた選択肢
になります。

次の章では、 設計理解を前提にしたうえでの「Easy Save」という選択肢について触れていきます。
【効率重視派向け】Easy Saveという選択肢
ここまで読んで、
- JSONセーブの設計思想は分かった
- やるべきことも理解できた
でも同時に、こんな気持ちになっていないでしょうか。
「正直、全部自前で作るのはちょっと大変そう…」
そんな人向けの現実的な選択肢が、Easy Save です。
Easy Saveは「考えなくていい魔法のツール」ではない
先に大事なことを言っておきます。
Easy Saveは、
セーブ設計を理解しなくても何とかしてくれる魔法のアセット
…ではありません。
むしろ、
- JSONセーブの考え方を理解している
- セーブ対象が整理されている
こうした前提があるときに、
実装コストを一気に下げてくれるツールです。
Easy Saveが向いているケース
Easy Saveが特に力を発揮するのは、次のような場面です。
- セーブ項目が増えてきた
- ファイル管理や例外処理が面倒
- 暗号化やバージョン管理も考えたい
自前実装だと、
- 保存形式の管理
- 例外時の復旧
- 将来の拡張対応
といった部分に、意外と時間を取られます。
Easy Saveは、
この「面倒だけど避けられない部分」をまとめて肩代わりしてくれます。
設計理解 → Easy Save導入、が一番安全
おすすめなのは、
- まずJSONでセーブ設計を理解する
- 構造が固まったらEasy Saveに置き換える
という順番です。
この順序で進めると、
- ブラックボックス化しにくい
- トラブル時に原因を追いやすい
というメリットがあります。
Easy Saveのチェックはこちら
設計を理解したうえで、
実装や保守の手間を減らしたい場合は、 Easy Saveはかなり有力な選択肢です。

次の章では、
JSONセーブでよくある誤解や、初心者がつまずきやすいポイントを整理します。
よくある誤解・注意点
JSONセーブは便利ですが、
理解が浅いまま使うと別の形でハマることがよくあります。
ここでは、初心者〜中級者が特につまずきやすい誤解と注意点を整理しておきます。
JSONにすればセーブ問題は解決する、という誤解
これは本当によくある誤解です。
JSONはあくまで「保存形式」であって、 セーブ設計そのものを代わりに考えてくれるわけではありません。
設計が整理されていない状態でJSONに移行すると、
- 巨大で読みづらいJSONができる
- どの値がどこで使われているか分からない
- 変更が怖くて触れなくなる
といった状態になりがちです。
JSONは設計が整理されているほど強くなる、 という性質を覚えておきましょう。
JsonUtilityは何でも保存できると思ってしまう
Unityの JsonUtility は便利ですが、万能ではありません。
- Dictionaryがそのまま使えない
- 一部の型は工夫が必要
この制約を知らずに設計すると、 後から「保存できない」「読み込めない」という問題に直面します。
だからこそ、
- セーブ用クラスはシンプルにする
- Unityのシリアライズ仕様を前提に考える
という意識が重要です。
最初から完璧な設計を目指しすぎない
セーブ設計に慣れていないうちは、 完璧な構造を最初から作ろうとしすぎるのも落とし穴です。
実際には、
- 作りながらデータは増える
- 不要な項目も出てくる
というのが普通です。
大切なのは、
「あとから直せる構造になっているか」
という視点です。
JSONセーブは、 この「あとから直せる余地」を作りやすい方式でもあります。
まとめ
この記事では、UnityにおけるJSON形式のセーブ/ロードについて、 単なる実装方法ではなく設計視点を中心に解説してきました。
最後に、ポイントを整理しておきましょう。
- PlayerPrefsは小規模・設定値向けで、万能ではない
- JSONは「構造化されたセーブ」を前提にすると非常に強い
- JSONは保存形式であって、設計そのものではない
- セーブ専用データを分離し、役割ごとに整理することが重要
- 最適化はパフォーマンスだけでなく、保守性も含めて考える
JSONセーブは、
「PlayerPrefsでは不安だが、いきなり大規模な仕組みは重い」
という個人開発者にとって、 非常に現実的でバランスの取れた選択肢です。
ただし、設計を考えずに導入すると、 JSONでも簡単に破綻します。
逆に言えば、
設計さえ押さえておけば、JSONは最後まで安心して使える保存方式
になります。
まずは、
- 何を保存したいのか
- どの単位でまとめるのか
を整理するところから始めてみてください。
その上で、 「実装の手間を減らしたい」「安定性を高めたい」と感じたら、 Easy Saveのようなツールを検討する、という流れが一番安全です。
参考文献
- Persistent Data: How to Save Your Game States and Settings(Unity公式ブログ)
- UnityでセーブデータをJSON形式で保存・読み込みする方法
- UnityでJSONを使ったセーブシステムを作る方法
- Unityでのセーブデータ設計について考える
- UnityでJSONを用いたセーブ/ロードの実装例
- Unityのセーブデータ管理まとめ(JSON保存)
- How to Save & Load Game Data in Unity(YouTube)
- Best way to save data in a Unity game?(Stack Overflow)
- Should I use ScriptableObjects or JSON to save data?(Reddit)
- PlayerPrefs.Save(Unity公式ドキュメント)
よくある質問(FAQ)
- QJSONセーブはスマホ(iOS / Android)でも問題なく使えますか?
- A
はい、基本的には問題なく使えます。
Unityでは
Application.persistentDataPathを使うことで、 iOS・AndroidそれぞれのOS仕様に沿った保存先が自動的に選ばれます。注意点としては、
- 保存頻度を上げすぎない
- 書き込み中にアプリが落ちる可能性を考慮する
といった点です。
特にスマホでは、 バックグラウンド遷移や強制終了が起きやすいため、 上書き保存の扱いには注意しましょう。
- QJsonUtilityとNewtonsoft.Jsonはどちらを使うべきですか?
- A
結論から言うと、 最初はJsonUtilityで十分です。
JsonUtilityは、
- Unity標準で追加ライブラリ不要
- 動作が軽い
- 基本的なセーブ用途には問題ない
というメリットがあります。
一方で、
- Dictionaryを多用したい
- 柔軟な変換処理が必要
といった場合は、Newtonsoft.Jsonの方が向いています。
ただし、自由度が高い分、 設計が甘いとデータ構造が崩れやすい点には注意が必要です。
- Qセーブデータは1ファイルと分割、どちらが正解ですか?
- A
これはケースバイケースですが、 中規模以上になりそうなら分割がおすすめです。
すべてを1ファイルにまとめると、
- 一部だけ初期化したいときに困る
- 保存失敗時の影響範囲が大きい
といったデメリットが出てきます。
役割ごとに、
- 設定系
- 進行データ
- インベントリ
などを分けておくと、 保守性・安全性の両方が高くなります。
最初はシンプルに始めて、 必要になったタイミングで分割する、という考え方でも問題ありません。











※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。
※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。