CrossRoad

XRを中心とした技術ブログ。 Check also "English" category.

Android Studioで作ったmoduleをUnityから呼ぶ方法

前回は、UnityからAndroid Studioで作った関数を呼ぶためのmodule作成方法をまとめました。

Android StudioでUnity向けmoduleを作る方法 - Cross Technology

今回は、前回作ったmoduleを元に、UnityからAndroidの関数を呼ぶ方法を紹介いたします。なお、前回ご紹介の通り、今回使い方を紹介しているAndroid StudioとUnityのプロジェクトは下記に公開しています。

GitHub - flushpot1125/UnityAndroidPluginTest

1. UnityでAndroid の関数を呼ぶための特殊クラスについて

Unityでは、Android nativeの関数を呼ぶために、特殊なクラスがいくつか提供されています。詳しくは公式マニュアルをご確認ください。

Android 用のプラグインのビルドと使用 - Unity マニュアル

Android nativeの関数を呼ぶための、代表的なクラスは下記の2つです。

AndroidJavaClass

Android側のstatic methodを呼び出すためのクラスです。C#でこのように記述します。

AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 

これで、unityPlayerという変数で"com.unity3d.player.UnityPlayer"というクラスにアクセスできるようになります。

実際は、Androidのクラスの中にあるstatic methodを呼ぶときに使います。(他の使い方もあるかもしれないのですが、私が調べた多数のサイトではstaticメソッドコール以外の使い方は発見できませんでした。もし他の使い方があれば教えていただけると嬉しいですm(_ _)m )

AndroidJavaObject

Android側のnon-static メソッドを呼び出すためのクラスです。C#でこのように記述します。

AndroidJavaObject plugin = new AndroidJavaObject("moduletest.test.com.nativeplugin.NativeMethod");

これでpluginという変数で"moduletest.test.com.nativeplugin.NativeMethod"というクラスにアクセスできるようになります。実際は、クラス内部のnon-static methodにアクセスするために使います。

2. Unityプロジェクトの作り方

いつもと変わらず作ればよいのですが、 Android Studioで作ったjarファイルは、Plugins/Android フォルダに入れてください。

UnityのPlugins/Android フォルダの場所

ここに入れないと認識されないのでご注意ください。その他、Android向けnatvie pluginを作るときの注意点はこちらにまとめました。こちらもご参考ください。

【2017/7更新】Android StudioでUnity向けmodule開発時のTips - Cross Technology

3. static関数と、non-static関数の呼び出し方について

確認用に、このようなプロジェクトを作りました。

GitHub - flushpot1125/UnityAndroidPluginTest

Unityで作ったAndroid native plugin用のサンプルプロジェクト画面

TestObject_StaticとTestObject_NonStaticオブジェクトに、それぞれスクリプトが付いており、uGUIのボタンを押すと、これらのスクリプトからAndroid Nativeの関数を呼び出します。

javaのメソッドには、staticをつける、つけないで二種類のメソッドがあります。staticをつけると、インスタンス化せずに、共通のメモリ領域から呼び出すことができます。

3-1. staticメソッドの呼び出し方法

このようなコードを書くことで呼び出せます。


gist0ea02351137df3906b8affef896841a6

AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 
	

は、メソッド呼び出しだけの場合不要です。Android側のActivityを呼び出す場合に使います。いろいろ検討していたときのコードが混じってしまいました。新しくpushしたgithubのコードではコメントアウト済みです。

plugin.CallStatic("staticFunction");

このCallStaticを使うことで、Android側の関数"staticFunction"を呼ぶことができます。前回のブログの再掲になりますが、Android Studio側ではこのようなコードが書かれています。


gist084d8d4a6cb21d80ee96273130d3a6ca

staticFunctionの中には、

UnityPlayer.UnitySendMessage("TestObject_Static","onCallBackShowResult","Static Method has been called!");

があります。

これはUnityのC#側にある、"TestObjcet_Static"というオブジェクトの、"onCallBackShowResult"というメソッドに対して、"Static Method has been called!"という文字列を送る、という意味です。

つまり、onCallBackShowResultメソッドは、Android側から呼び出され、いわゆるコールバックの働きをします。
(関数名は自由に指定できるので、この名前でなくても問題ありません)

これらの操作をつなげることで、

  • uGUIの"Call static Function"というボタンを押す
  • Android側の"staticFunction"というメソッドが呼ばれる
  • "staticFunction"から、Unityの"onCallBackShowResult"メソッドに対して文字列を返す
  • "onCallBackShowResult"メソッドがuGUIのTextに"Static Method has been called!"を表示する

が実現できます。

3-2. non-staticメソッドの呼び出し方法

「Unity Android native plugin」のようなキーワードで調べると、ほとんどの場合、AndroidJavaClassを使ってstaticメソッドを呼び出す例しか書かれていません。

今回のようなシンプルな例の場合はそれでもよいのですが、実際はAndroid nativeで提供されている機能をUnityで使おうとすると、staticにできないようなメソッドも存在します。

今回紹介する方法を使うことで、non-staticのメソッドも呼び出すことができます。

と、前振りを書きましたが、色々調べて検証した結果、non-staticメソッドを呼び出す方法はとてもシンプルでした。下記のように、AndroidJavaObjectクラスを使って、Android native側のクラスをオブジェクト化するだけです。


gist06c3059a3ce64b32a303a71b152e3909

staticメソッドを呼び出すときは、AndroidJavaClassを使ったのですが、これをAndroidJavaObjectに置き換えたこと、callStaticではなくcallメソッドで呼び出す、以外は同じです。

3-3. 動作確認

githubに公開したプロジェクトをUnity5.3以上で開きます。
(私の使った環境がUnity5.3のためです。本来はバージョン依存はないです)

GitHub - flushpot1125/UnityAndroidPluginTest

UnityからOpen Projectを選び、「AndroidUnityTest2」フォルダを指定して開くと、下記のような警告がでますが、Continueをクリックすると開くことができます。

AndroidUnityTest2プロジェクトを開いたときの警告画面

あとは、test.unityというシーンを開き、Build Settingsでこのシーンをビルド対象に追加し、Android向けにビルドしてください。下記はXperiaZ3で確認した結果です。Call Static Function、Call non static Function というボタンを押すと、それぞれ、Android側のjavaに書いたstring文字列を表示させています。

AndroidUnityTest2の動作実現のgif画面

4. 終わりに

UnityとAndroid native機能を連携させる、についてはあまり情報がなかったので、思ったよりも自分の理解を整理するのに時間がかかりました。

また、今回の方法を使うことで、staticメソッドとnon-staticメソッドをUnityから呼べるようになりますが、実際はAndroid側のソースコードがもっと複雑で、この呼び出しだけでは対応できないことが多いです。

次の記事では、そういう複雑なAndroid側のコードをUnityで呼び出すときに困る点や対応方法などを書いていこうと思っています。