【Unity】JsonUtility でObject を JSON 化できるパターンと出来ないパターン
Object と JSON 文字列とを相互に変換してくれる Unity 公式の JsonUtility。速度も速く便利ですが、書き方を間違えるとJSON化されなかったりするので注意が必要です。
目次
JSON 化できる例
最もシンプルな構造
[System.Serializable]
public class Weapon
{
// Id
public int id;
// 武器名
public string name;
// 攻撃力
public int atk;
}
void Run()
{
var weapon = new Weapon()
{
id = 1,
name = "SWORD",
atk = 5,
};
var json = JsonUtility.ToJson(weapon);
Debug.Log(json);
}
class には System.Serializable 属性を付与します。
{
"id": 1,
"name": "SWORD",
"atk": 5
}
JSON化出来ています。
入れ子にする
階層的な JSON ってよくありますよね。
[System.Serializable]
public class Status
{
public int atk;
}
[System.Serializable]
public class Weapon
{
public int id;
public string name;
public Status status;
}
void Run()
{
var weapon = new Weapon()
{
id = 1,
name = "SWORD",
status = new Status()
{
atk = 5,
},
};
var json = JsonUtility.ToJson(weapon);
Debug.Log(json);
}
武器ステータスを class に分けて入れ子にしてみました。
{
"id": 1,
"name": "SWORD",
"status": {
"atk": 5
}
}
階層でもJSON 出力されます。
配列やリスト
[System.Serializable]
public class Effect
{
public int id;
}
[System.Serializable]
public class Status
{
public int atk;
}
[System.Serializable]
public class Weapon
{
public int id;
public string name;
public Status status;
public Effect[] effect;
}
void Run()
{
var weapon = new Weapon()
{
id = 1,
name = "SWORD",
status = new Status()
{
atk = 5,
},
effect = new Effect[]
{
new Effect()
{
id = 10,
},
new Effect()
{
id = 20,
}
},
};
var json = JsonUtility.ToJson(weapon);
Debug.Log(json);
}
{
"id": 1,
"name": "SWORD",
"status": {
"atk": 5
},
"effect": [
{
"id": 10
},
{
"id": 20
}
]
}
サンプルは配列ですが List に変わっても結果は同じです。
JSON 化できない例
Dictionary
JsonUtility は Dictionary に対応していません。
[System.Serializable]
public class Effect
{
public int value;
}
[System.Serializable]
public class Status
{
public int atk;
}
[System.Serializable]
public class Weapon
{
public int id;
public string name;
public Status status;
public Dictionary<int, Effect> effect;
}
void Run()
{
var weapon = new Weapon()
{
id = 1,
name = "SWORD",
status = new Status()
{
atk = 5,
},
effect = new Dictionary<int, Effect>()
{
{
1,
new Effect()
{
value = 10,
}
},
{
2,
new Effect()
{
value = 20,
}
}
}
};
var json = JsonUtility.ToJson(weapon);
Debug.Log(json);
}
{
"id": 1,
"name": "SWORD",
"status": {
"atk": 5
}
}
Dictionary にした Effect が無視されてしまいます。エラーログは出ません。
自動実装プロパティ
見落としがちですが get/set 書いちゃダメです。
[System.Serializable]
public class Weapon
{
public int id { get; set; }
public string name { get; set; }
}
void Run()
{
var weapon = new Weapon()
{
id = 1,
name = "SWORD",
};
var json = JsonUtility.ToJson(weapon);
Debug.Log(json);
}
癖で書いてしまうことがあるかもしれません。
{}
何も出力されません。
手を加えるとJSON化できるもの
private な変数
private な変数はそのままでは JSON 化できません。
[System.Serializable]
public class Weapon
{
private int id;
private string name;
}
private な変数は SerializeField 属性を付与することで JSON 化できます。
[System.Serializable]
public class Weapon
{
[SerializeField]
private int id;
[SerializeField]
private string name;
}
void Run()
{
var weapon = new Weapon(1, "SWORD");
var json = JsonUtility.ToJson(weapon);
Debug.Log(json);
}
{
"id": 1,
"name": "SWORD"
}
まとめ
これくらい網羅しておけば、迷うことも無いのではと思います。速度面でも結構早いのでうまく活用していきたいですね。