以前の記事でAndroidのプラグインの関数を呼び出す方法を書きました。
逆にAndroidからUnityのメソッドを呼び出したい場合、もう一手間必要となります。
目次
今回は以前の記事でネイティブプラグインの作り方を理解されてから読んでいただけると幸いです。
また、上記のプロジェクトを引き続き使います。
事前準備:コールバックに必要な jar ファイルをインポート
Android側からUnityのクラスを認識するために jar ファイルをインポートする必要があります。
公式サイトの「UnityPlayerActivity Java コードの拡張」の以下の部分に従って、classes.jar を探します。
これを行うには、まず Unity/Android に付属している classes.jar を探します。このファイルは Unity をインストールしたフォルダー(Windows であれば C:\Program Files\Unity\Editor\Data 、MacOSX であれば /Applications/Unity )のサブフォルダー PlaybackEngines/AndroidPlayer/Variations/mono または il2cpp/Development or Release/Classes/ にあります。
自分はMacを使っているので、今回は /Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/il2cpp/Development/Classes/classes.jar を使ってみます。
これをAndroidStudioプロジェクトの libs フォルダに置きます。
置いたらAndroidStudioのメニューから
File > Project Structure
と選択し、モジュールのDependencies を表示します。
左下の「+」ボタンから File Dependency を選択。
libs に置いた classes.jar を追加します。
このままだと作成したライブラリに classes.jar そのものが含まれてしまうので、dialog-pluin モジュールの build.gradle ファイル の末尾に以下を追加します。
android.libraryVariants.all{ variant-> variant.outputs.each{output-> output.packageLibrary.exclude('libs/classes.jar') } }
これでUnityのクラスを認識できるようになりました。
UnitySendMessage 関数でレッツ・コールバック
いよいよUnityの関数を呼び出すのですが、それにあたって必要な情報があります。
- シーン内のGameObjectの名前
- 関数名
イメージとしてはUnityにある SendMessage 関数をJavaで叩くかんじです。
UnitySendMessage("GameObject名","関数名","引数");
でコールバックできます。
前回作ったプロジェクトのNativeDialogクラスを修正し、ダイアログのどのボタンが押されたかを通知するようにしました。
package jp.co.test.dialog_plugin; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import static com.unity3d.player.UnityPlayer.UnitySendMessage; public class NativeDialog { static public void showMessage(Context context, String title, String message) { // ボタン入力を受け取るリスナ DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int which) { switch(which) { case DialogInterface.BUTTON_POSITIVE: // Yesボタン UnitySendMessage("CallbackGameObject", "OnClickOk", "OKが押されたよ!"); break; case DialogInterface.BUTTON_NEGATIVE: // Noボタン UnitySendMessage("CallbackGameObject", "OnClickNo", "今回もだめだったよ..."); break; default: break; } } }; // リスナを指定してダイアログ表示 new AlertDialog.Builder(context) .setTitle(title) .setMessage(message) .setPositiveButton("YES, YES, YES!", listener) .setNegativeButton("...No?", listener) .show(); } }
ビルドしてUnityのプロジェクトにインポートしましょう。
Unity側で受け取る
UnityでシーンにCallbackGameObjectという名前でオブジェクトを配置し、以下のスクリプトをアタッチします。
ひたすらダイアログをコールバックしまくるというウイルスちっくな逸品です。
using UnityEngine; using System.Collections; public class AndroidPlugintest : MonoBehaviour { void Start () { ShowDialog ("もうやってられまへーん"); } void ShowDialog(string message) { #if UNITY_ANDROID // Javaのオブジェクトを作成 AndroidJavaClass nativeDialog = new AndroidJavaClass ("jp.co.test.dialog_plugin.NativeDialog"); // Context(Activity)オブジェクトを取得する AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject context = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); // AndroidのUIスレッドで動かす context.Call ("runOnUiThread", new AndroidJavaRunnable(() => { // ダイアログ表示のstaticメソッドを呼び出す nativeDialog.CallStatic ( "showMessage", context, "おっさんの主張", message ); })); #endif } // OKボタンが押された void OnClickOk(string text) { ShowDialog (text); } // Noボタンが押された void OnClickNo(string text) { ShowDialog (text); } }
ちょっと工夫すればメッセージを受け取るGameObjectもUnityから指定できますね。試してみてください。
Unityでビルドエラーが出る場合
Unityでビルドしたときに以下のエラーが出る場合があります。
IOException: Failed to Move File / Directory from 'Temp/StagingArea/android-libraries/dialog-plugin-debug/classes.jar' to 'Temp/StagingArea/android-libraries/dialog-plugin-debug/libs/classes.jar'.
この場合、build.gradleのclasses.jar除外設定をしてあるか確認してください。
よくわからない場合、もう一度最初からこの記事をよんだほうがいいよ。
- 参考
https://docs.unity3d.com/ja/current/Manual/PluginsForAndroid.html http://qiita.com/abpla/items/a8e4c70953859cdc7c54