Unity 5.3で実装されたJsonUtilityの注意点まとめ
閉じる
閉じる

新しい記事を投稿しました。シェアして読者に伝えましょう

×

Unity 5.3で実装されたJsonUtilityの注意点まとめ

2015-12-11 00:24
    以下は全て Unity v5.3.0f4 のとき書いたものです。
    Unityのバージョンアップや、単に筆者の勘違いなどで、皆さんの手元の状況とは異なる可能性があります。

    Unity5.3のJsonUtilityを使ってみた感想を書いてみました。何か変な所があったらぜひ @kraihd までどうぞ。



    ■DictionaryやHashtableはシリアライズできない

    公式にも呼びかけられている大事なポイント。
    シリアライズ前に、KeysとValuesを変換して保持しておく用のListや配列が必要になるかもしれない。(追記:ToArrayはToListよりもパフォーマンスが落ちるらしいので配列よりはListのほうがいい)



    ■配列のネストは1つまで

    多次元配列、配列内配列(ジャグ配列)、配列のコレクションなどは、JSONにシリアライズしてくれない
    多次元配列(int[,] とか)は、.NET標準のシリアライザも対応してないので仕方ない。
    しかし int[][]List<int[]>List<List<int>>なども、JsonUtilityは華麗にスルーする。
    とても不便。
    一応、公式は他のシリアライザの5倍以上の速度があると言っているので、Array.ConvertAll とか String.Join とかを使って、配列を自力で文字列に変換する余裕はあるかも?

    もうひとつの解法としては、なぜか、配列の中のクラスの中の配列はOK
    例えば、int[] のフィールドが1つあるだけのクラス AnotherClass を用意して、元のクラスには AnotherClass[] のフィールドを用意する。すると普通にシリアライズしてくれる。自力変換に比べて楽だけど、大量のデータを扱う場合容量が嵩むので注意。
    もちろんListでもいいし、クラスではなく構造体でも大丈夫。
    (……なんで?)


    ■TransformはMonoBehaviourの派生クラスではない

    インスペクタに表示されているから間違えやすいけど。なのでJsonUtilityではシリアライズできない。
    ゲームオブジェクト丸ごとシリアライズしようとすると普通に大掛かりな処理をすることになりそう。



    上記のような問題を解決すべく、変換前後に処理を挟むためのイベント関数が用意してある。
    その名も OnBeforeSerialize()OnAfterDeserialize()
    しかし罠はそこにも……!



    ■OnBeforeSerializeとOnAfterDeserializeは、MonoBehaviour継承クラスでしか呼ばれない

    メソッド名から察した人もいるかもしれない。でも自分は1日経つまで気づきませんでした。
    この2つも、OnEnableとかOnApplicationPauseとかと一緒で、イベント関数というMonoBehaviourの機能にすぎない。
    なので、特にGameObjectにアタッチとかしない普通のクラスでは使えない。
    ScriptableObject継承クラスであっても例外ではない

    この2つを使わず、クラスにSerialize/Deserializeメソッドを記述するのが大安定な気がする。
    MonoBehaviourでもそうしたほうが、シリアライズ前・デシリアライズ後以外にも、シリアライズ後・デシリアライズ前に何かすることもできる。

    追記:ISerializationCallbackReceiver を使うという手もあるもよう。



    ちなみに、

    ■実は非同期で実行できる

    これは普通に嬉しい所。UnityEngine名前空間の機能の多くは普通別スレッドで動かせないけど、これに関してはOK。ローディングの別スレッドの中でも使える。(ResourcesとかAssetBundleとかでないなら)
    今後、 ToJsonAsync などの実装が検討中と言われているけど、スレッドを使って今から自力で作ることも十分可能。




    12/12追記:ある意味一番大事なことを書き忘れていた。

    ■インスタンスをJSONに、JSONをインスタンスに変換するものである

    変換する以外のことはできない。例えば、JSONライブラリと聞いて思い浮かべる、「変数名や構文の文字列をキーとして値を取り出す」ような機能はない。データ形式を必ずクラスとして記述しておく必要があるので、どんな名前の変数があるのか開発段階で未知である箇所には手が出せない。
    要するにJSONというデータ形式を扱うための機能ではない
    ユーティリティとは何だったのか。速度ゆえの犠牲?
    それとインスタンスと結びついていない static なものに対して使うこともできない。(これは工夫次第でなんとかなるかも)



    • 前の記事
      これより過去の記事はありません。
    広告
    コメントを書く
    コメントをするには、
    ログインして下さい。