【Unity】ゲームデータをセーブするためのJSONの使い方【JSON.NET】
こんにちは、システム開発部のうのです。最近少しづつ Unity でゲームを作っています。とても楽しいです。今日は Unity で JSON.NET というライブラリを使ってみた話です。
ゲームを作っていて、データを保存したいと思うときが必ずあると思います。Unity ではこういう時は「Playerpref」という API を使うのですが、この API 、実は 数値、文字列型にしか対応していません。これについてはかなり前から知っていたのですが、正直問題だと思っていませんでした。
しかし、いざ Unity でセーブを実装したときにかなりつまずいたので、これについて少し喋ろうと思います。
JSON にできない!
以前から知っていて問題に思っていなかったのは、「文字列なら保存できるんだから、JSON にすれば一発だろう」と思っていたからですね。
普段、業務で使っている php や java script このあたりとても便利だったので、高をくくったわけです。
Unity には Json Utility というAPI があったので、これは簡単だと思いましたね。
ところが実際に使ってみると……
コインの枚数が入っている Coins には数字が入っているけど、Decks には一切の値が入っていない……!(連想配列、Dictionary が入っている想定でした)
これは Unity の Json Utility の仕様によるものでした。
なぜ JSON にできない? Unity の JSON Utility について
答えはマニュアルにありました。
Unity 付属の JSON Utility は、基本的に Unity の仕組み内で定義された構造体をシリアライズするためのものです。
つまり GameObject はシリアライズが可能だけど、 配列はもちろん、List(配列的なモノ)、Dictionary(連想配列的なモノ)も対象じゃない、ということです。
List や Dictionary こそ Json にしたいのに……
さらに公式の説明には 「配列などを使いたいときは、構造体でラップしてね!」と書いてあります。
つまり
- Dictionary は利用できない
- List in List など階層構造になっているものはその各階層をいちいち構造体でラップする必要がある
- 構造が完璧に決まっていて、かつコーディングがされていないと保存できない!
ということ。うーんこれは困る……。
JSON.NET を使おう
Unity の Json Utility は使うのをやめて、他の手段を取ることにしました。JSON.NET の導入です。
導入は以下の記事を参考に。なんと Packages\manifest.json に追記するだけで完了します。ラクチン!
- https://github.com/jilleJr/Newtonsoft.Json-for-Unity/wiki/Installation-via-Git-in-UPM
- https://github.com/jilleJr/Newtonsoft.Json-for-Unity/wiki/Install-Converters-via-Git-in-UPM
超簡単な使い方説明はこちらに。
Unity でオブジェクトをシリアライズして、オブジェクトに戻す例が↓です。特に準備もいらないのが良いですね。
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Utilities;
public class TestCodeForJson : MonoBehaviour {
public void Test(Object obj) {
string serializedObj = JsonConvert.SerializeObject(obj);
return JsonConvert.DeserializeObject(serializedObj);
}
}
結果・とてもスムーズ
使った結果、 List, Dictionary もかなりスムーズに変換してくれました。うれしい。階層構造もサポートしてくれています。Directory内リストもこのとおり。
ただ、デシリアイズした Directory から値を取り出すときは、型を意識する必要はありました。型の情報はJSONにしたときに失われるので。
やることは適切にキャストしてあげることだけですので、非常に簡単でした。