はじめに
Unity での JSON パース方法についてです。すこし制約があるみたいですが JsonUtility
がよさそうです。
使い方
使い方はめっちゃ簡単!下記のように [System.Serializable]
をつけるだけ!
1 2 3 4 5 6 7 8 9 10 11 |
[System.Serializable] public class Hoge { public string text; public int num; public bool flag; } string hogeJson = "{\"text\": \"hoge\", \"num\": 3, \"flag\": true}"; Hoge hoge = JsonUtility.FromJson<Hoge>(hogeJson); // text: hoge, num: 3, flag: True Debug.Log($"text: {hoge.text}, num: {hoge.num}, flag: {hoge.flag}"); |
色々なJSON
オプショナル
JSON に num のキーが存在しない場合、下記のように 0 が設定されました。
1 2 3 4 5 6 7 8 9 10 11 |
[System.Serializable] public class Hoge { public string text; public int num; public bool flag; } string hogeJson = "{\"text\": \"hoge\", \"flag\": true}"; Hoge hoge = JsonUtility.FromJson<Hoge>(hogeJson); // text: hoge, num: 0, flag: True Debug.Log($"text: {hoge.text}, num: {hoge.num}, flag: {hoge.flag}"); |
その他いろいろやってみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// numがnull string hogeJson = "{\"text\": \"hoge\", \"num\": null, \"flag\": true}"; // text: hoge, num: 0, flag: True // textなし(これはtextがnullになりました) string hogeJson = "{\"num\": 3, \"flag\": true}"; // text: , num: 3, flag: True // textがnull string hogeJson = "{\"text\": null, \"num\": 3, \"flag\": true}"; // text: , num: 3, flag: True // flagなし string hogeJson = "{\"text\": \"hoge\", \"num\": 3}"; // text: hoge, num: 3, flag: False // flagがnull string hogeJson = "{\"text\": \"hoge\", \"num\": 3, \"flag\": null}"; // text: hoge, num: 3, flag: False |
string のキーなしのときだけ null になりました。
入れ子
Serializable アノテーションをつけたクラスのプロパティに Serializable アノテーションをつけたクラスを利用できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[System.Serializable] public class Hoge { public string text; public Fuga fuga; } [System.Serializable] public class Fuga { public string text; } string hogeJson = "{\"text\": \"hoge\", \"fuga\": {\"text\": \"fuga\"}}"; Hoge hoge = JsonUtility.FromJson<Hoge>(hogeJson); // text: hoge, fuga: [text: fuga] Debug.Log($"text: {hoge.text}, fuga: [text: {hoge.fuga.text}]"); |
null の場合。
1 2 3 4 5 6 7 |
// fugaなし string hogeJson = "{\"text\": \"hoge\"}"; // text: hoge, fuga: [text: ] // fugaがnull string hogeJson = "{\"text\": \"hoge\", \"fuga\": null}"; // text: hoge, fuga: [text: ] |
下記のように配列もあつかえます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
[System.Serializable] public class Hoge { public string text; public Fuga[] fugaList; } [System.Serializable] public class Fuga { public string text; } string hogeJson = "{\"text\": \"hoge\", \"fugaList\": [{\"text\": \"fuga1\"}, {\"text\": \"fuga2\"}]}"; Hoge hoge = JsonUtility.FromJson<Hoge>(hogeJson); string fuga = ""; int count = hoge.fugaList.Length; for (int i = 0; i < count; i++) { if (i == 0) { fuga = "{" + $"text: {hoge.fugaList[i].text}" + "}"; } else { fuga += ", {" + $"text: {hoge.fugaList[i].text}" + "}"; } } // text: hoge, fugaList: [{text: fuga1}, {text: fuga2}] Debug.Log($"text: {hoge.text}, fugaList: [{fuga}]"); |
null の場合。
1 2 3 4 5 6 7 8 9 10 11 |
// fugaListが空 string hogeJson = "{\"text\": \"hoge\", \"fugaList\": []}"; // text: hoge, fugaList: [] // fugaListがなし string hogeJson = "{\"text\": \"hoge\"}"; // fugaList == null になりました(hoge.fugaList.Lengthでクラッシュ) // fugaListがnull string hogeJson = "{\"text\": \"hoge\", \"fugaList\": null}"; // text: hoge, fugaList: [] |
プロパティ名とキー名が違う場合
下記のように JSON のキーと異なるプロパティ名にしたい場合、ちょっとめんどうなことをしないといけないようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
[System.Serializable] public class Hoge : ISerializationCallbackReceiver { public int num; [SerializeField] // JSONの変換に含む [HideInInspector] // Inspector非表示 private string hoge_name; [System.NonSerialized] // JSONの変換に含まない public string hogeName; // Serializeの前(=ToJsonの前)に呼ばれる public void OnBeforeSerialize() { hoge_name = hogeName; } // Deserializeの後(=FromJsonの後)に呼ばれる public void OnAfterDeserialize() { hogeName = hoge_name; } } string hogeJson = "{\"hoge_name\": \"hoge\", \"num\": 10}"; Hoge hoge = JsonUtility.FromJson<Hoge>(hogeJson); // hogeName: hoge, num: 10 Debug.Log($"hogeName: {hoge.hogeName}, num: {hoge.num}"); |
おわりに
キーとプロパティが違うときだけめんどくさそうですが他のに比べると動作が速いらしいのでとりあえず JsonUtlity を使えばいいのかなと思います。制限があるらしいですがこれだけできればたいていの場合は問題ないと思います!(エラーハンドリングどうするんだろ?)
参考
- JSON Serialization
- JsonUtility
- JsonUtility をつかって Unity で JSON を取り扱う方法
- UnityのJsonUtilityの細かい10の疑問をいまさら検証した
コメント