Unity - Json.NET:List, Dictionary などをJSONで扱う -
初めに
データのセーブに用いられる JsonUtility ではList や Dictionary などは対象外なため、制約が強いです。そこでより汎用性の高い Json.NET についてまとめます。
Index
Json.NETのドキュメント
Json.NET の導入の仕方
PackageManager の Add package from git URL... に次の URL を入力すれば導入できます。
com.unity.nuget.newtonsoft-json@3.0
Newtonsoft Json が追加されれば ok です。
※AssetStoreなどほかの導入方法もあります。
Json.NET の使い方
使い方の基本
(例1)最も基本的なスクリプト
オブジェクトをシリアライズ、デシリアライズするだけのスクリプト
using System.Collections; using System.Collections.Generic; using UnityEngine; using Newtonsoft.Json; //追加 public class JsonSample : MonoBehaviour { private void Start() { int num = 1; //シリアライズ var jsonint = JsonConvert.SerializeObject(num); Debug.Log(jsonint); //デシリアライズ var outputnum = JsonConvert.DeserializeObject(jsonint); Debug.Log(outputnum); } }
(実行結果)
(例2)List や配列がまざっている、保存するデータのクラスを作っている
using System.Collections; using System.Collections.Generic; using UnityEngine; using Newtonsoft.Json; //追加 public class JsonSample : MonoBehaviour { //JSONに変換するオブジェクトのクラスを取得 private JsonType jsonType = new JsonType(); private void Start() { jsonType.Key1 = "test01"; jsonType.Key2 = 2; jsonType.Key3 = new List<string>(); jsonType.Key3.Add("aaa"); jsonType.Key3.Add("bbb"); float[] numbers = new float[]{0.1f, 0.2f}; jsonType.Key4 = new List<float[]>(); jsonType.Key4.Add(numbers); //シリアライズ var jsonBody = JsonConvert.SerializeObject(jsonType); Debug.Log(jsonBody); //デシリアライズ JsonType outPut = JsonConvert.DeserializeObject<JsonType>(jsonBody); Debug.Log(outPut.Key1); Debug.Log(outPut.Key2); Debug.Log(outPut.Key3); Debug.Log(outPut.Key4); } } //JSONに変換するオブジェクトのクラス [JsonObject] public class JsonType { [JsonProperty("Key1")] public string Key1 { get; set; } [JsonProperty("Key2")] public int Key2 { get; set; } [JsonProperty("Key3")] public List<string> Key3 { get; set; } [JsonProperty("Key4")] public List<float[]> Key4 { get; set; } }
(実行結果)
ファイルに書き込み、セーブ・ロードできるようにする
JsonUtility の際に作ったスクリプトを改造し、ファイルに書き込みができるようにします。FromJson や ToJson などの JsonUtility の機能を使っていた部分を変えています。ファイルの書き込み、読み込みについての説明は JsonUtility の記事をご覧ください。
using System.Collections; using System.Collections.Generic; using UnityEngine; using Newtonsoft.Json; using UnityEditor; //AssetDatabaseを使うために追加 using System.IO; //StreamWriterなどを使うために追加 using System.Linq; //Selectを使うために追加 public class JsonSample : MonoBehaviour { private JsonType jsonType = new JsonType(); //保存先 string datapath; void Awake() { //保存先の計算をする //これはAssets直下を指定. /以降にファイル名 datapath = Application.dataPath + "/TestJson02.json"; } private void Start() { JsonType jsonData = new JsonType(); //JSONファイルがあればロード, なければ初期化関数へ if(FindJsonfile()) { jsonData = loadJsonData(); Debug.Log(jsonData.Key1); } else { Initialize(); } } //セーブするための関数 public void saveJsonData(string text) { StreamWriter writer; //JSONファイルに書き込み writer = new StreamWriter(datapath, false); writer.Write (text); writer.Flush (); writer.Close (); } //JSONファイルを読み込み, ロードするための関数 public JsonType loadJsonData() { string datastr = ""; StreamReader reader; reader = new StreamReader (datapath); datastr = reader.ReadToEnd (); reader.Close (); return JsonConvert.DeserializeObject<JsonType>(datastr); } //JSONファイルがない場合に呼び出す初期化関数 //初期値をセーブし, JSONファイルを生成する public void Initialize() { jsonType.Key1 = "test01"; jsonType.Key2 = 2; jsonType.Key3 = new List<string>(); jsonType.Key3.Add("aaa"); jsonType.Key3.Add("bbb"); float[] numbers = new float[]{0.1f, 0.2f}; jsonType.Key4 = new List<float[]>(); jsonType.Key4.Add(numbers); var jsonBody = JsonConvert.SerializeObject(jsonType); saveJsonData(jsonBody); } //JSONファイルの有無を判定するための関数 public bool FindJsonfile() { //TestJson02はファイル名 string[] assets = AssetDatabase.FindAssets("TestJson02"); Debug.Log(assets.Length); if(assets.Length != 0) { string[] paths = assets.Select(guid => AssetDatabase.GUIDToAssetPath(guid)).ToArray(); Debug.Log($"検索結果:\n{string.Join("\n", paths)}"); return true; } else { Debug.Log("Jsonファイルがなかった"); return false; } } } [JsonObject] public class JsonType { [JsonProperty("Key1")] public string Key1 { get; set; } [JsonProperty("Key2")] public int Key2 { get; set; } [JsonProperty("Key3")] public List<string> Key3 { get; set; } [JsonProperty("Key4")] public List<float[]> Key4 { get; set; } }
LINQ to JSONについて
JSON オブジェクトを LINQ を用いて操作するため機能として、LINQ to JSON があります。
名前空間に次のテキストを入れることで使用できます。
ドキュメント
最後に
JsonUtility は制約が強く、不便さを感じる場面もあります。Json.NETは使えるに越したことはないように感じます。