この記事でのバージョン
Unity 6000.3.4f1
はじめに
UnityにはJsonUtilityというJSONデータを手軽に扱えるクラスがあります。
今回は、そのJsonUtilityでJsonからデジリアライズ(復元)した時のちょっとした注意点の話。
デジリアライズ時は、引数なしのコンストラクタが自動で実行
例えば以下のようにコンストラクタを備えたクラスを、
[Serializable] public class TestData { public int a = 1, b = 2, c = 3; //引数なしのコンストラクタ public TestData() { a = 10; b = 20; c = 30; Debug.Log($"引数なしのコンストラクタ実行、a={a}, b={b}, c={c}"); } //引数ありのコンストラクタ public TestData(int a, int b, int c) { this.a = a; this.b = b; this.c = c; Debug.Log($"引数ありのコンストラクタ実行、a={a}, b={b}, c={c}"); } }
JsonUtilityを使ってJsonからデジリアライズすると、
引数がないコンストラクタが自動で実行され、その後にJsonの値が反映されます。
public class JsonCtorCheck : MonoBehaviour { private void Start() { //aの値だけを設定した、Jsonを作成 var json = "{\"a\":456}"; Debug.Log($"Json = {json}作成、デジリアライズ前"); //JsonUtilityでデシリアライズ、ログで中身確認 var obj = JsonUtility.FromJson<TestData>(json); Debug.Log($"デジリアライズ後、a={obj.a}, b={obj.b}, c={obj.c}"); } }
![]() |
コンストラクタ実行後にJsonの値が反映されるので、Jsonの中身と違う値になる事はありませんが、
Jsonに含まれない値がコンストラクタ内で変わったり、
コンストラクタ内の処理が予期せぬタイミングで実行されるという事に繋がるので注意が必要です。
なお、最近のドキュメント(Unity6.3)ではこの事が仕様として載っていますが、
Field initializers and any logic in the default constructor are executed during deserialization.
(フィールド初期化子およびデフォルトコンストラクタ内のロジックは、デシリアライゼーション時に実行されます。)
昔のドキュメント(Unity 2022.3)には逆の事が書いてあります。
the constructor for the object is not executed during deserialization
(オブジェクトのコンストラクタは、デシリアライズ中に実行されません)
しかし、どうやら前からこの仕様だったらしくドキュメントの間違いが修正された形のようです。
