【学習】Unity:アイテム所持とセーブ入門(第3回)― 消えないデータ:PlayerPrefs と JSON
第2回 までは、所持データは メモリ上だけにありました。
しかしゲームでは、よくこうなります。
アプリを終了しても、前回の続きから始めたい。
今回はその最小手段として PlayerPrefs と、複数アイテムを 1 本の文字列にまとめる JsonUtility を使います。
シリーズ
- 目次(00)
- 前回: 第2回
- 第3回(本記事):
PlayerPrefsと JSON- 次回: 第4回:
OwnedItemsDataとInstance
今日のゴール
PlayerPrefs.SetInt/GetIntで 数値 1 つが Play をまたいで残ることを確認する- アイテムが複数あると
SetIntを量産しがちで辛い、という 問題意識 を持つ - クラス → JSON 文字列 →
PlayerPrefs.SetStringの流れを体験する - 初回起動(キーがまだない)ときの分岐を書ける
ステップ① PlayerPrefs で数値 1 つ
保存
void Start()
{
PlayerPrefs.SetInt("Gold", 100);
PlayerPrefs.Save();
}読み込み
int gold = PlayerPrefs.GetInt("Gold");
Debug.Log(gold);実験
- Play → Stop → もう一度 Play
- 値が残ることを確認する(エディタ上の挙動は Project に依存するため、確実に学ぶなら実機ビルドも試すとよいです)
ステップ② 問題意識:アイテムは複数ある
例:
- ポーション 3
- 剣 1
- 鍵 5
SetInt を種類の数だけ書くのは、管理が面倒で キーが増えすぎます。
ステップ③ JSON でまとめる(イメージ)
テキストとして、たとえば次のような 1 塊にします(イメージ)。
{ "gold": 100 }Unity では JsonUtility が クラスと JSON 文字列の相互変換を担当します。
ステップ④ 最小例:SaveData クラス
[System.Serializable]
public class SaveData
{
public int gold;
}保存
SaveData data = new SaveData();
data.gold = 100;
string json = JsonUtility.ToJson(data);
PlayerPrefs.SetString("SAVE_MIN", json);
PlayerPrefs.Save();読み込み(初回ガード付き)
if (!PlayerPrefs.HasKey("SAVE_MIN"))
{
Debug.Log("まだセーブがありません");
return;
}
string json = PlayerPrefs.GetString("SAVE_MIN");
SaveData data = JsonUtility.FromJson<SaveData>(json);
Debug.Log(data.gold);ステップ⑤ 第2回の ItemManager への載せ方(考え方)
やりたいことはシンプルです。
「ownedItems のリスト全体」を JSON にして、1 つのキーに保存する」
string json = JsonUtility.ToJson(this); // MonoBehaviour なら this でも試せるが…
PlayerPrefs.SetString("ITEM_DATA", json);授業では、まず SaveData のような普通のクラスで成功体験を作り、そのあと **「保存したいフィールドだけを持つクラス」**に寄せると安全です。
教材上の注意
MonoBehaviourをFromJsonで 完全復元するのは、授業の主役にしにくいです(コンポーネントはシーンにアタッチされるものだから)。
だから次回、データだけを持つクラス(OwnedItemsData型)に進みます。
重要ポイント
- キー名(例:
"SAVE_MIN")は 保存と読込で同じにする [Serializable]を忘れると JSON 化できない/空になることがある- 初回はキーが無い …
HasKeyで分岐する
プログラムの流れ
ゲーム中にデータが更新される
↓
JsonUtility.ToJson で文字列化
↓
PlayerPrefs.SetString で保存(必要なら Save)
↓
次回起動で GetString → FromJson で復元発展アイデア
- セーブ直前に
Debug.Log(json)で、中身の文字列を目で追う - エディタメニューで
PlayerPrefs.DeleteAll()を叩き、初回動作を何度も試す
次に進む
データを MonoBehaviour から切り離し、どこからでも同じ Instance で触れる形にすると、シーン設計が楽になります。