UnityでJSONをあつかう - LitJSON
About
ここでは"LitJSON"を利用したJSONの読み取りについて解説します。
- Unity_LitJSONTest.zip
- Unity4.0プロジェクト
LitJSONとは
"LitJSON"は、JSON読み書き用のライブラリで、ライセンスはPublicDomainとなっています。また2013年3月現在、2007年まで開発・管理がされていることを確認しています。ソースコードを全て熟読したわけではありませんが、エンコード・デコードなどの必要な機能に加えて、Exceptionが用意されていたり、シリアライズ・デシリアライズができるので、十分な機能は提供されていると思ってよいと思います。バージョンが0.5となっているのが気にかかりますが、エンコード・デコードする分には気になりません。
LitJSONはSourceForgeの公式ないし、Unifycommunityからダウンロードするのが良いと思います (GitやSubversionでも公開されています。公式からリンクが確認できます。)
ライセンスがPublicDomainなので、著作の掲載義務もなしに自由に利用できる点が最大の長所でしょう。開発が止まっているとはいえ、基本機能は十分に提供されていることから、LitJSONを土台にして独自に開発を進めてしまうのもありだと思います。
複数のファイル(ソースコード)から構成されることから、他のJSONライブラリと比較して使いにくい印象を受けますが、アセットの中に専用のフォルダを用意して、そこに全てのソースコードを入れてしまえば呼び出し側からは分からないので気になりません。また、dllにして[Pluginsフォルダ]の中に入れてしまうのも良いと思います。公式からダウンロードした場合には、dllも含まれています。
LitJSONで実現できること
LitJSONで実現できることを確認しておきます。ここではデコードとデシリアライズ(Deserialize)しか紹介しないためです。
- JSONテキストのデコード(JSONテキスト → LitJson.JsonData)
- JSONテキストの出力(エンコードではなく独自のWriterを用いる)
- JSONテキストのデシリアライズ(JSONテキスト → 任意の型のインスタンス)
- JSONテキストへのシリアライズ(任意の型のインスタンス → JSONテキスト)
- その他
LitJSONではJSONテキストはJsonData型のインスタンスとしてデコードされます。またデシリアライズする機能を持っていて、任意の型のインスタンスとして取得する機能も提供されています。
LitJSONの詳細なあつかいについては公式のドキュメントを参照することをおススメします。シンプルなサンプルコードが掲載されているので、十分に理解することができると思います。
JSONテキストのデコードとデシリアライズ
デコードとデシリアライズのサンプルを示します。見ての通り、複雑な手順を必要とせずにスムーズにあつかうことができます。LitJson.JsonMapperを利用することで通常のデコードかデシリアライズかができます。
デコードする場合には、ToObjectメソッドをジェネリクス(Generic(s))をつけずに呼び出します。この場合には独自のLitJson.JsonDataが戻り値として与えられます。ハッシュテーブル(Dictionary)のようにあつかい、キーを与えることで対応する値を取得することができます。
一方でデシリアライズする場合、あらかじめデシリアライズするクラスを定義しておきます。ここでは"DecodeDataクラス"を定義しました。デシリアライズするとは言うものの、C#でいうところの、[System.Serializable]アトリビュートは不要のようです。デシリアライズする場合にはジェネリクスをつけてToObjectメソッドを呼び出します。デシリアライズする場合の注意点について、ソースコードの後に記述します。
その他の値を例にとったサンプル、エンコードなどのその他の利用方法は、公式のドキュメントに掲載されています。
//必須ではないらしい //[System.Serializable] private class DecodeData { public string message; public int num; public double dummy; } // Use this for initialization void Start () { //仮のJSONテキスト. string jsonText = "{\"message\":\"SampleText\",\"num\":1}"; //JSONテキストのデコード. LitJson.JsonData jsonData = LitJson.JsonMapper.ToObject(jsonText); //データの取得 string message = (string)jsonData["message"]; int num = (int)jsonData["num"]; //出力して確認する-1. print(message + "," + num); //Deserializeする. DecodeData decodeData = LitJson.JsonMapper.ToObject<DecodeData>(jsonText); //データを更新する. decodeData.message += "plus"; decodeData.num += 1; //出力して確認する-2. print(decodeData.message + "," + decodeData.num); }
デシリアライズの注意点
デシリアライズするクラスを用意するとき、JSONテキストに与えられる各プロパティ値と同じ名前のPublicな変数を用意しておく必要があります。対応付けが確認できない場合は、実行時にエラーが発生します。逆に、デシリアライズするクラスの中に、JSONテキストには含まれない変数を用意しておくことはできます。もっともその変数に代入するなどしなければ"宣言されているが参照されない"という警告が出ますが、実行に不具合は来しません。
またlong型とint型の型変換の際に問題が生じているようです。long型の値があると、int型にCastしようとしてエラーになることが確認されています(Referenceに参照を掲載しました)。データの都合上longで受け取る必要がある場合にはdoubleですべて受けてしまって任意にCastするか、LitJsonを編集して対応できるようにする必要があります。
参考までにMiniJSONではint型の値もlong型としてあつかい、任意にintにCastさせるような手段を取っています。
Reference
- UnityでJSONを扱う - しのぶの日記(技術編)
- long型の値をCastする際に生じる問題についてコメント欄で討論されている