unity には JsonUtility があるじゃん
お手軽だし、速度面はおそらく最速レベル。はいこれで決まりー。
かつて私もそう思った時期がありました。一瞬ですが。
JsonUtility には弱点があったのです。
- List<T> が使えない
- DateTime が使えない
- Dictionary が使えない
①List<T> は、List<T> をメンバーに持つクラスを作り、それをパースする、②もまぁ…パースする前に日付の文字列にするなどで対応……、③ は………いや、どうにか出来なくないけど面倒になってきた。
そう、出来るならクラスをまるっと渡してそのまま Json 文字列にして欲しいです。
それを可能にするのが Json.Net というわけです。
インストール方法
Package Manager > 左上の+ > Add package from git URL... > com.unity.nuget.newtonsoft-json > Add
Newtonsoft Json が追加されれば成功です。
実は適当に持ってきた Newtonsoft.Json.dll を Assets/ 下に入れてもエディター上では動作しますが、ビルドした時に動作しなくなるので注意しましょう。
テストコード
using System.Collections.Generic; using System.IO; using Newtonsoft.Json; using UnityEngine; public class NewBehaviourScript : MonoBehaviour { class SaveData { public string StringValue; public int IntValue; public Dictionary<string, int> Dics; [JsonIgnore] public int IgnoreValue; } SaveData saveData; void Start() { saveData = new SaveData() { StringValue = "abcdef", IntValue = 12345, IgnoreValue = 67890, Dics = new Dictionary<string, int>() { { "No.1", 1 }, { "No.2", 2 }, { "No.3", 3 }, }, }; // saveData → json string json = JsonConvert.SerializeObject(saveData); // json → loadData var loadData = JsonConvert.DeserializeObject<SaveData>(json); Debug.Log($"StringValue: {loadData.StringValue}"); Debug.Log($"IntValue: {loadData.IntValue}"); Debug.Log($"IgnoreValue: {loadData.IgnoreValue}"); foreach (var pair in loadData.Dics) { Debug.Log($"Dic: {pair.Key} -> {pair.Value}"); } } }
saveData → json テキスト → loadData とデータを受け渡し、loadData の中身を表示します。
ポイントの解説
using Newtonsoft.Json;
JsonConvert を使うための常套句。
[JsonIgnore]
json 化したくないメンバーの上にこれを書いておけば、json 化を防ぐことができます。
サンプルでは IgnoreValue のみ json 化しません。
string json = JsonConvert.SerializeObject(saveData);
saveData の中身を json テキストに変換します。変換したテキストはこんな感じ。
{"StringValue":"abcdef","IntValue":12345,"Dics":{"No.1":1,"No.2":2,"No.3":3}}
開発時など、json の値をパッと見わかりやすくしたいのであれば、インデントをつける事もできます。
string json = JsonConvert.SerializeObject(saveData, Formatting.Indented);
{ "StringValue": "abcdef", "IntValue": 12345, "Dics": { "No.1": 1, "No.2": 2, "No.3": 3 } }
var loadData = JsonConvert.DeserializeObject(json);
json テキストを変換し、loadData の中に入れます。
loadData の表示結果
IgnoreValue は [JsonIgnore] によって保存されなかったので、loadData では初期値の 0 になっています。
それ以外は saveData と同じになりました。
速度がそれほど必要ないのであれば…
そもそも速度が必要になるような頻度で json にすることも稀なので、汎用性を取って Json.Net にしておいてはいかがでしょうか。
後からどんなメンバーが追加されても安心です。