UnityとAndroidネイティブの連携:JavaClassの呼び出し

UnityとAndroidネイティブの連携 の投稿一覧

Androidプラグインをjarとして出力し、そのjarをUnityから呼び出すところまで実機検証できたので覚え書きとしてまとめました。
今回はJavaClassを呼び出すのみになります。

環境

  • OSX Yosemite v10.10.4
  • Unity v5.1.2f1
  • AndroidStudio v1.3.1
  • 検証端末 Nexus7(2012) v5.1.1

Androidプラグインを生成するまで

  1. 空のプロジェクトを作成,モジュールをJavaLibraryとして作成
  2. build.gradleの編集
  3. javaクラスの作成
  4. jar出力
空のプロジェクトを作成,モジュールをJavaLibraryとして作成

AndroidStudioで、[Add No Activity]を選択し空のプロジェクトを作成します。
次に、File > New ModuleからJavaLibraryのモジュールを作成します。
javalibraryselect
私は今回、testlibという名称で作成しています。

build.gradleの編集
配置はJavaLibraryの方。最初に作成したappディレクトリ配下ではないので注意。androidnativetestpath

.jarを2つ追加
AndroidネイティブからUnityPlayerActivityを使えるようにするためにclasses.jarを、
Androidの機能を使えるようにするためandroid.jarを、
JavaLibraryのbuild.gradleを開いてdependenciesに追記します。

apply plugin: 'java'

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile files('/Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/release/bin/classes.jar')  /*追記する行,classes.jarを追加する*/
    compile files('/Users/ユーザ名/Library/Android/sdk/platforms/android-22/android.jar')  /*追記する行,android.jarを追加する*/
}
この記事で書いた方法で、直接build.gradleファイルに追記しなくてもAndroidStudio上から直接パスを指定して追加できるかと思ったものの、できなかった。
この方法を取るには、プロジェクトに作成したlibsディレクトリに2つの.jarファイルを含めておけばできるようだ。
Unityから動作させる上で、コーディング上は生成されるjarの名前を気にする必要は無いと思う。なので今回はjarファイル名やバージョンをビルド時に自動で変更挿入する行について省略している。

追記後、AndroidStudioのSync Project with Gradle Filesを実行しておく。
syncgradle

javaクラスの作成

Androidプラグインとなるjavaクラスを作成します。
今回は確認用として、toast表示機能のみを付けています。

package com.example;

import android.app.Activity;
import android.widget.Toast;

import com.unity3d.player.UnityPlayer;

public class AndroidNativeTest {
    public static void showToast() {
        final Activity activity = UnityPlayer.currentActivity;
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(activity, "successful!", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
jar出力

AndroidStudioのTerminalを開き、作成したJavaLibraryのディレクトリに移動します。私の場合は先述のtestlibに移動しました。

hoge-pc:app ユーザ名$ cd /Users/ユーザ名/AndroidStudioProjects/TestApplication/testlib

次にjarを出力します。

hoge-pc:app ユーザ名$ ./../gradlew jar

TerminalウィンドウにBUILD SUCCESSFULと表示されれば、jar出力は成功です。
testlib/build/lib直下にtestlib.jarが出力されています。

AndroidStudioでの操作は終わり、ここからはUnityの操作に移ります。

Unityから生成したAndroidプラグインを呼び出すまで

  1. 空のプロジェクトを作成
  2. jarファイルの置き場となるディレクトリを作成する
  3. プラグインを呼び出すC#スクリプトを作成する
  4. 空のGameObjectを作成し、C#スクリプトをアタッチする
  5. ビルド、実機で実行できるか確認
空のプロジェクトを作成

Unityの新規プロジェクトを作成します。

jarファイルの置き場となるディレクトリを作成する

Assets/Plugins/Android/直下に、先ほど作成したtestlib.jarファイルを配置します。
プロジェクトを新規作成した段階ではこのディレクトリは存在しないので、自分で作成します。
putjar

プラグインを呼び出すC#スクリプトを作成する
using UnityEngine;
using System.Collections;

public class Caller : MonoBehaviour {

	private static string JAVA_CLASS_NAME = "com.example.AndroidNativeTest";
	private static string JAVA_METHOD_NAME = "showToast";

	// Use this for initialization
	void Start () {
		using ( AndroidJavaClass plugin = new AndroidJavaClass(JAVA_CLASS_NAME)){
			plugin.CallStatic(JAVA_METHOD_NAME);
		}
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}
空のGameObjectを作成し、C#スクリプトをアタッチする

普通にCreateEmptyして生成されたGameObjectに、先ほど作成したC#スクリプトをアタッチするだけ。

ビルド、実機で実行できるか確認

devicess
toast表示が正常に動いた。

トーストの表示は前述のToast.LENGTH_SHORTだと、2秒経つと消えてしまう。Unityのスプラッシュロゴが表示されている間に消えてしまっていることもあるので、その場合は表示する秒数を増やすと良いと思います。
UnityEditor上では検証できない。
実行しようとしても、”Exception: JNI: Init’d AndroidJavaClass with null ptr!”のエラーとなる。

後日、UnityPlayerNativeActivityを拡張したものをプラグイン化して検証してみます。
→検証しました:UnityとAndroidネイティブの連携:UnityPlayerNativeActivityを拡張して呼び出し