Unityでのデータ保存はどっちが最適?
Unityでのデータ保存、どっちを使うべき?
PlayerPrefs vs ScriptableObject
はじめに
Unityでゲームやアプリを作るとき、設定値やスコアなどのデータを保存する方法としてよく使われるのがPlayerPrefsです。一方で、ScriptableObjectという仕組みもあり、特に定数や構成情報の管理に便利です。
しかしこの2つ、どちらも「保存できるような気がする」し、「使い方が似ているようで違う」。混乱することも少なくありません。
この記事では、それぞれの特性・使い分け・具体的なメリットデメリットを比較し、どんな場面でどちらを使うべきかを整理します。
PlayerPrefsとScriptableObjectの比較
| 特性 | PlayerPrefs | ScriptableObject |
|---|---|---|
| 永続性 | ◎(保存可) | △(エディタで保存。実行中は非永続) |
| データ量 | 少量向き | 中〜大量もOK |
| 書き込み速度 | 高速(ただし軽量向け) | 基本は読み取り専用。書き込みには工夫が必要 |
| シーン跨ぎ | ◯ | ◯(アセット参照で可能) |
| Git管理 | ×(バイナリ) | ◯(アセット化可能) |
| 保存タイミング | 明示的(Save()必要) |
エディタ上で即時反映(ビルド時は固定) |
用途別おすすめの使い分け
PlayerPrefsが向いているケース
- ユーザーが設定する「音量」や「通知ON/OFF」などの設定値
- プレイ実績:スコア・進行ステータス
- アプリ終了後も保持したい値
PlayerPrefs.SetInt("highScore", 12345);
PlayerPrefs.Save();
ScriptableObjectが向いているケース
- アイテム一覧やステージ構成など定数的なデータ管理
- JSONやCSVから読み込んだ初期データの保持
- エディタ拡張やバランス調整で頻繁に編集するパラメータ
[CreateAssetMenu(fileName = "StageData", menuName = "Game/StageData")]
public class StageData : ScriptableObject {
public int stageId;
public string title;
public EnemyData[] enemies;
}
ScriptableObjectで保存したくなったら?
ScriptableObjectはUnityエディタ上では書き換え・保存可能ですが、アプリ実行中に値を変えてもその内容はアセットに保存されません。
アプリ内で値を変更・永続化したい場合は以下の工夫が必要です:
- 一時的な変更は、別変数に保持する(ScriptableObject自体はテンプレートとして使う)
- JSON形式で保存・復元する
-
EditorUtility.SetDirty()+AssetDatabase.SaveAssets()でエディタ保存(ビルド時不可)
保存形式とアクセス性の違い
| 項目 | PlayerPrefs | ScriptableObject |
|---|---|---|
| 保存先 | OSごとのレジストリ or plist | Unityプロジェクト内の.assetファイル |
| データ構造 | int, float, stringのみ | ネストや配列、参照可能 |
| 読み書き方法 |
Set/Getによる即時反映 |
アセットとして参照。基本は読み取りのみ |
実際に使ってみた感想(+JSON保存連携の工夫)
実際のプロジェクトでは、以下のような組み合わせがとても効果的でした:
- ScriptableObjectでステージやアイテムの定義を持たせ、
- PlayerPrefsやJSONでユーザーの進捗を保存・復元
「保存したい」のか「共有したい」のか、目的に応じて使い分けるのが肝でした。
また、ScriptableObjectのデータをJSON化してPlayerPrefsに保存するという構成も非常に有効でした。
- アプリ終了時に、ScriptableObjectの内容をJSONにしてPlayerPrefsへ保存
- アプリ起動時に、PlayerPrefsからJSONを読み取り、ScriptableObjectに反映
この方式を使うと、アクセスは高速なScriptableObjectを介しつつ、永続化はPlayerPrefsで担うことができ、膨大な量のデータを扱う場合にもパフォーマンス面・管理面で非常に効果的でした。
まとめ
-
PlayerPrefsは「ユーザーが触る設定や結果の保存」向け -
ScriptableObjectは「ゲーム内の構成・定義の共通管理」向け - 永続化の目的や対象に応じて、適切に選ぶとトラブルも減る
- 両者を組み合わせれば、より柔軟で管理しやすいプロジェクトになる
ブログでもUnityや個人開発ネタを発信中です!
開発ノウハウやアプリ制作過程、Unity連携系のハマりポイントなど
より深掘りした内容をブログにまとめています。
▶ https://syunpp.com
公開中のアプリ一覧はこちら!
実際にUnityで開発してリリース済みのアプリ一覧をまとめています。
▶ https://syunpp.com/公開中のアプリ一覧/
YouTubeショートでもゲーム開発の裏側を公開中!
Unityで制作中のゲームの進捗や演出テスト、実装の様子を
ショート動画でタイムラプス形式にまとめて発信しています。
▶ https://www.youtube.com/@syunpp_8413/shorts
Discussion