はじめに
今日は昨日の続き、UnityとAndroidネイティブプラグインのやり取りにJsonを使おうと思います。
今回はAndroidですが、特にAndroid特有のものは使っていないので応用は聞くと思います。しらんけど
昨日の記事はこちら
昨日の復習
ネイティブプラグインのJavaコードからUnityのC#コードに結果を返すときはUnitySendMessage
関数を使うんでした。
ただ、文字列しか返せないので微妙です。
今回はJsonで渡してオブジェクトごと通信してやろうという会です。
JavaにおけるJson
JavaではJsonを扱う際にJacksonというライブラリを使うのが主流なようです。
導入していきます。
Jacksonの導入
簡単です。ネイティブプラグインのbuild.gradle
に追記するだけです。
...//略
dependencies {
//追記部分
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.15.0-rc1'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.15.0-rc1'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.15.0-rc1'
//ここまで
...//略
これでsyncしてもらえればJava側は導入完了です。らくちん。ただ、あとでUnityにもこちらを書かないといけません。
Jacksonの使い方
Jacksonがメインではないので簡単に…
public static TimePickerDialog.OnTimeSetListener TimerDialogCallback() {
return new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int hour, int min) {
//オブジェクト化
SerializedTime time = new SerializedTime(hour, min);
//Json化(ここからJackson)
ObjectMapper mapper = new ObjectMapper();
String timeJson = null;
try {
timeJson = mapper.writeValueAsString(time);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//(ここまで)
//Unityに送信
UnityPlayer.UnitySendMessage("listenerObj", "TimeSetCallback", timeJson);
}
};
}
今回シリアライズしているのはこのクラス。(これぐらいならJsonじゃなくてもいいやろとか言わない)
ちなみに、java.io.Serializableインターフェース
をクラスに実装しているとエラーになりました。
public class SerializedTime {
private int hour;
private int min;
public SerializedTime(int hour, int min) {
this.hour = hour;
this.min = min;
}
public int getHour() {
return hour;
}
public int getMin() {
return min;
}
public void setHour(int hour) {
this.hour = hour;
}
public void setMin(int min) {
this.min = min;
}
}
ObjectMapper
というクラスをインスタンス化して、そのインスタンスのwriteValueAsString()
メソッドを使うだけです。
このメソッドの戻り値から結果である文字列が取得できます。
そして、UnitySendMessage()
メソッドでC#側に送信します。
UnityにおけるJson
Unityにはみんな大好きJsonUtility大先生がいらっしゃいますよね。
結構好きでよく使ってます。
値を受け取る。
Jsonから変換するクラスを作ります。
using System;
[Serializable]//これ大事
public class TestJsonClass
{
public int hour;
public int min;
public TestJsonClass(int min, int hour)
{
this.min = min;
this.hour = hour;
}
}
Serializable
属性だけ忘れないでくださいね。
ちなみに、知らなかったんですが
setter
とgetter
を付けるとシリアライズされないみたいです。注意
JsonUtilityで受け取ったJson形式の文字列を変換していきます。
using UnityEngine;
public class ListenerTest : MonoBehaviour
{
public void TimeSetCallback(string message)
{
var json = JsonUtility.FromJson<TestJsonClass>(message);
Debug.Log($"{json.hour}:{json.min}");
}
}
よっしゃ!勝ち!!!、、、と言いたいんですけど私はここから4時間ぐらいの戦いに入るとは思ってませんでした。
でも大丈夫。5秒で解決します。そうこの記事ならね。
UnityのビルドにJacksonを含める。
UnityはAndroidのビルド時に、aarのビルド時にも作ったbuild.gradle
ではなく全く別のものを使います。
なので、Jacksonねぇじゃねぇか!って怒られます。
ただ、Unityのbuild.gradle
はカスタマイズが加えられておりいくつかのファイルに分かれています。
どこに書くか、、、これをネットで探しまくりました。
正解発表
まず、プロジェクト設定(Project Settings)の下線部、Custom Lancher Gradle Template
にチェックを入れてください。
そうすると、そのgradleファイルが生成され、パスも下に記載されます。
そのファイルを編集していきます。
...//略
dependencies {
implementation project(':unityLibrary')
// 追記部分
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.15.0-rc1'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.15.0-rc1'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.15.0-rc1'
// ここまで
}
...//略
ここに先ほどと全く同じものを記載すれば大丈夫です。
こんなに簡単なのに4時間ぐらい使ったの悔しい。
ビルドして実機で確認
はい。このようにログを出力できました。
実は、ログの状態は前回の記事と全く変わってません。Jsonで変換してるかしてないかです。
このJson化が必要になるときは来るんですかね。どうなんでしょう。
古のスマホをデバック用として使っているのかだって?普段使いだよ!!
おわりに
なんも書くことないっすわ。お付き合いありがとうございました。
また、Tips的なこと書けそうになったら書きますねー。
んじゃ、また!