UnityでJsonといえば
Unity5.3から公式でJSONに対応されたので、
今JSON使いたい!ってなった場合、例として以下の手法があります。
手法 | 目的 | Dictionary |
---|---|---|
JsonUtility | 構造が確定しているJSON使いたい | 不可 |
MiniJson | 手軽にシンプルなJSONを使いたい | 可 |
MiniJson+JsonNode | ある程度複雑なJSONを手軽に使いたい | 可 |
問題点
上記の手法で殆どの場合解決すると思うのですが、
楽に扱うことは出来ても、「ネストの深さ」までの自由度は得られません。
例えば、実行中にユーザーが用意した任意のJSONを読み込む、というようなことをしたい場合、ある程度テンプレートが定まっていることが前提条件となってしまいます。
つまるところ、JsonNodeだと
node(json["hoge"]["bool"].Get<bool> ());
となるようなところを、
node.Get<bool> (new object[]{"hoge", "bool"}));
こんな風に取得出来るようにしようという話です。
JsonNodeを拡張する
##スクリプト
任意のネストの深さのの値を取得できるようにJsonNodeのGet<T>()
を改良しました。
Get<T>()
と差し替えて使えます。
JsonNode
public Type Get<Type>(params object[] param){
object node = this.obj;
for (int i = 0; i < param.Length; i++) {
if (param [i] is int)
node = (object)(((IList)node) [(int)param [i]]);
if (param [i] is string)
node = (object)(((IDictionary)node) [(string)param [i]]);
}
if (typeof(Type) != node.GetType ())
throw new Exception ("\n" + typeof(Type) + " => " + node.GetType ());
return (Type)node;
}
##使い方
以下のようなJSONを例に説明します。
test.json
{
"fuga":1.23,
"hoge":{
"bool":true,
"long":123,
"list":[123,456]
}
}
で、Unity側からはこんな感じで使えます。
void start(){
TextAsset text = Resources.Load ("test.json") as TextAsset;
JsonNode json = JsonNode.Parse (text.text);
//拡張版の書き方
print (json.Get<double> (new object[]{"fuga"}));
print (json.Get<bool> (new object[]{"hoge", "bool"}));
print (json.Get<long> (new object[]{"hoge", "long"}));
print (json.Get<long> (new object[]{"hoge", "list", 1}));
//従来のJsonNodeの書き方でもOK
print (json["hoge"]["bool"].Get<bool> ());
}
まぁ、ここまで自由度を上げる必要性が出てくる場面はあまり無いと思いますが。
#参考