はじめに
Android JavaでのUnity Pluginを作成をまとめました。
ツールは以下のバージョンを使用しています。
他のバージョンでも大丈夫だと思いますがaarを扱うためUnity5以上を対象としています。
- macOS 10.12
- Unity 5.3.4
- Android Studio 2.2.3
なぜこの記事を書こうと思ったかというと書籍などではAndroid Pluginの項は大体Toast表示等で終わってしまうからです..
(Unity→Androidの呼び出しのみ)
今回はUnityからAndroidのソースを呼び出しコールバックを受け取るところまで行います。
(Unity→Android, Android→Unityの呼び出し)
さりげなく前回の記事から9ヶ月越しの続編です。
以下の順序で説明します。
- 1 開発方法について
- 1.1 aarの作成について(AndroidStudio)
- 1.2 Unityのaar組み込みについて(Unity)
- 2 ソースコードについて
- 2.1 Unity→Androidの呼び出しソースコードについて(Unity)
- 2.2 Android→Unityの呼び出しソースコード(AndroidStudio)
- 3 Tips
1 開発方法について
1.1 aarの作成について(AndroidStudio)
Androidで適当なプロジェクトを作成し、New ModuleでAndroid Libraryを指定します。
Moduleのlibsフォルダにunityのclasses.jarを追加します。(ここではunity5.3.4-classes.jarにrenameしました)
classes.jarの場所は以下Unityマニュアルに書いてあります。
引用) UnityPlayerActivity Java コードの拡張
https://docs.unity3d.com/ja/current/Manual/PluginsForAndroid.html
まず Unity/Android に付属している classes.jar を探します。このファイルは Unity をインストールしたフォルダー(Windows であれば C:\Program Files\Unity\Editor\Data 、MacOSX であれば /Applications/Unity )のサブフォルダー PlaybackEngines/AndroidPlayer/Variations/mono または il2cpp/Development or Release/Classes/ にあります。
classes.jarを追加しSyncをおこなうとUnityのクラスが使用可能になります↓
ビルド時にunityのclasses.jarは作成するaarから外すようにします。
unityのclasses.jarを外さないとunityでAndroid向けビルドを行ったときにunityのclasses.jarが重複となりビルドに失敗します。
android.libraryVariants.all { variant ->
variant.outputs.each { output ->
output.packageLibrary.exclude('libs/unity5.3.4-classes.jar')
}
}
上記でUnity向けAndroidライブラリ作成の準備は完了です。
AndroidStudioのメニュー > Build > Make Module
を選択するとaarが作成されます。
この時、Proguardの設定にご注意ください。
Proguardでメソッド名やクラス名が変わるとUnityから呼び出す時にClassNotFoundExceptionになります。
1.2 Unityのaar組み込みについて(Unity)
1.1で作成したaarをAssets > Plugins > Androidにドラッグするだけです。
なぜこれだけで動作するのかというと、そういうunityの仕様のためです。
詳細は以下を見てください。
参考) Android ライブラリプロジェクト
https://docs.unity3d.com/ja/current/Manual/PluginsForAndroid.html
参考) 特殊なフォルダー名
https://docs.unity3d.com/jp/current/Manual/SpecialFolders.html
また、Activity追加や権限変更などでAndroidManifest.xmlを変更する場合、同じくAssets > Plugins > Androidに追加します。
引用) UnityPlayerActivity Java コードの拡張
https://docs.unity3d.com/ja/current/Manual/PluginsForAndroid.html
新しいAndroidManifest.xml を作成することも必要です。
AndroidManifest.xml ファイルも Assets->Plugins->Android フォルダーに配置する必要があります。(カスタムマニフェストを配置すると、デフォルトの Unity Android マニフェストを完全にオーバーライドします)。
〜〜
ここまでがPlugin作成と組み込み手順です!(とてもざっくり)
次は実際のコード呼び出し方法を説明します。
〜〜
2. ソースコードについて
2.1 Unity→Androidの呼び出しソースコードについて(Unity)
一番簡単な方法はAndroidJavaObject(AndroidJavaClass)の使用です
インスタンスであればAndroidJavaObject、インスタンス不要なクラスへのアクセスはAndroidJavaClassで使い分けます。
staticなメソッドであればCallStatic、通常のメソッドはCallを呼びます。
以下マニュアルにサンプルコードが掲載されています。
参考) AndroidJavaObject Call
https://docs.unity3d.com/ja/current/ScriptReference/AndroidJavaObject.Call.html
2.2 Android→Unityの呼び出しソースコード(AndroidStudio)
Android側からUnityの処理を呼び出すことが必要なケースがあります。
Android Java側でイベントハンドラをおこなう場合や
UnityがJavaのクラスを呼び出す際に非同期で値を返して欲しい場合などです。
上記のような場合はcom.unity3d.player.UnityPlayerクラスのUnitySendMessageメソッドを使用します。
com.unity3d.player.UnityPlayer.UnitySendMessage(
GameObjectName, //string ゲームオブジェクト名
MethodName, //string メソッド名
message //string 送信する値
);
以下マニュアルの通り、Unity側で対象のゲームオブジェクト内コンポーネントに以下形式でメソッドを定義する必要があります。
引数は文字列で1つのみなので複数データ送信はJSONなどに変換する必要があります。
複数人での開発の際はあらかじめインターフェイスを定義するのが良いと思います。
void MethodName(string message)
function MethodName(message:string)
参考) ネイティブコードから C#/JavaScript をコールバックする
https://docs.unity3d.com/jp/current/Manual/PluginsForIOS.html
3 Tips
Android Java上でUI操作を扱う場合、UIスレッド以外から操作を行うとIllegalStateExceptionが発生します。
Unityから呼び出す処理でUI操作を行う場合は、以下のようにUIスレッドで行うようにしてください。
import android.app.Activity;
import com.unity3d.player.UnityPlayer;
public void someUIAction() {
final Activity activity = UnityPlayer.currentActivity;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
//UI操作の処理
}
});
}
まとめ
UnityからAndroid Javaの呼び出しはAndroidJavaObject, 逆はUnitySendMessageでという話でした。
つまづきどころ、環境構築もまとめたのでUnityでのAndroid Plugin開発は
// C++での開発などに手を出さなければ
上記で大体できるようになると思います。
参考になれば幸いです。