PlayerPrefsではなくJSON保存に切り替えるときに知っておきたい制約と実装Tips
はじめに
Unityでのデータ永続化にはPlayerPrefs
が手軽に使えますが、より柔軟なデータ構造や複数項目をまとめて管理したい場面ではJSONファイル保存が便利です。
私自身も開発中のプロジェクトでPlayerPrefs
からJSONベースの保存方式に移行しましたが、その中でUnity標準のJsonUtility
には予想外の制約がいくつも存在することに気付きました。本記事では、それら制約とその回避方法を解説します。
UnityにおけるJSON運用の基本
Unityでは以下の2種類のJSON変換手段が一般的です:
JsonUtility
(Unity標準)Newtonsoft.Json
(外部ライブラリ。通称:Json.NET)
このうち、JsonUtility
は軽量で依存関係が不要な反面、扱えるデータ構造に多くの制限があります。
JsonUtilityの制約とその対処法
以下はUnity標準のJsonUtility
を使った場合に遭遇した代表的な制約です。
1. Dictionaryが保存できない
[System.Serializable]
public class SaveData
{
public Dictionary<string, int> scoreDict; // ×JsonUtilityでは保存不可
}
回避策
- 独自のシリアライズ可能な
SerializableDictionary
を使う - 保存時に
List<KeyValuePair<string, int>>
などに変換して書き出す
2. 抽象型や継承型の保存ができない
[System.Serializable]
public class Animal { public string name; }
public class Dog : Animal { public int barkPower; }
public class Zoo {
public Animal myPet; // 実体がDogでもbarkPowerは保存されない
}
回避策
- 継承を避け、明示的にすべての型情報を持つ構造に分解する
- Json.NETに切り替えて
TypeNameHandling
オプションで対応
3. ListのListが保存できない
[System.Serializable]
public class GridData
{
public List<List<int>> mapGrid; // ×Unityでは失敗することが多い
}
回避策
List<Row>
のような中間クラスを設ける
[System.Serializable] public class Row { public List<int> columns; }
[System.Serializable] public class GridData { public List<Row> rows; }
4. private変数、[NonSerialized]変数は保存されない
[System.Serializable]
public class SaveData {
private int hiddenValue; // ×保存されない
}
対策
public
+[SerializeField]
が必要- UnityのInspectorと同じルールが適用される
実装パターン例:JSONの読み書きを一元化する
public static class JsonSaveManager
{
public static void Save<T>(string fileName, T data)
{
string json = JsonUtility.ToJson(data);
string path = Path.Combine(Application.persistentDataPath, fileName);
File.WriteAllText(path, json);
}
public static T Load<T>(string fileName)
{
string path = Path.Combine(Application.persistentDataPath, fileName);
if (!File.Exists(path)) return default;
string json = File.ReadAllText(path);
return JsonUtility.FromJson<T>(json);
}
}
保存ファイルの場所に注意
Application.persistentDataPath
:各プラットフォームで安全に保存可能- Android/iOSで確認する場合は
adb
やXcodeでログ確認・ファイル出力が必要
まとめ
- Unity標準の
JsonUtility
は軽量ですが制限が多い - 複雑な構造を扱うなら
Json.NET
も検討価値あり - 保存対象の構造体はシンプル・publicフィールドベースに保つと安全
- 保存・読み込みはラップクラスで一元化すると管理しやすい
ブログでもUnityや個人開発ネタを発信中です!
開発ノウハウやアプリ制作過程、Unity連携系のハマりポイントなど
より深掘りした内容をブログにまとめています。
▶ https://syunpp.com
公開中のアプリ一覧はこちら!
実際にUnityで開発してリリース済みのアプリ一覧をまとめています。
▶ https://syunpp.com/公開中のアプリ一覧/
YouTubeショートでもゲーム開発の裏側を公開中!
Unityで制作中のゲームの進捗や演出テスト、実装の様子を
ショート動画でタイムラプス形式にまとめて発信しています。
▶https://www.youtube.com/@syunpp_8413/shorts
コメント