LoginSignup
75

More than 5 years have passed since last update.

突然仕事でUnity向けのSDKやPluginを作ることになった人向け資料<Android実践編>

Last updated at Posted at 2017-02-28

はじめに

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を指定します。

スクリーンショット 2017-02-28 1.32.10.png

Moduleのlibsフォルダにunityのclasses.jarを追加します。(ここではunity5.3.4-classes.jarにrenameしました)
classes.jarの場所は以下Unityマニュアルに書いてあります。

スクリーンショット 2017-02-28 1.37.41.png

引用) 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のクラスが使用可能になります↓

スクリーンショット 2017-02-28 1.41.43.png

ビルド時にunityのclasses.jarは作成するaarから外すようにします。
unityのclasses.jarを外さないとunityでAndroid向けビルドを行ったときにunityのclasses.jarが重複となりビルドに失敗します。

build.gradle
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にドラッグするだけです。

スクリーンショット 2017-02-28 2.08.39.png

なぜこれだけで動作するのかというと、そういう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メソッドを使用します。

Java側の処理
com.unity3d.player.UnityPlayer.UnitySendMessage(
    GameObjectName, //string ゲームオブジェクト名
    MethodName, //string メソッド名
    message //string 送信する値
);

以下マニュアルの通り、Unity側で対象のゲームオブジェクト内コンポーネントに以下形式でメソッドを定義する必要があります。
引数は文字列で1つのみなので複数データ送信はJSONなどに変換する必要があります。
複数人での開発の際はあらかじめインターフェイスを定義するのが良いと思います。

C#
void MethodName(string message)
Javascript
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スレッドで行うようにしてください。

Java側の処理
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++での開発などに手を出さなければ
上記で大体できるようになると思います。
参考になれば幸いです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
75