読者です 読者をやめる 読者になる 読者になる

いんでぃーづ

個人でゲーム開発してる上で吸収したモノたち紹介。UnityからGIMPまでなんでも。デザインとかゲーム論まで語っちゃうよ的なアレ。

MENU
{スポンサーリンク}

Unity用のAndroidプラグインを作ってみる

Unity Android

AndroidiPhoneの通知機能やらなにやらを使いたいときはよくあります。 アセット使えば手っ取り早いんですけど、かゆいところに届かないところもあるので、自前で用意する方法をちょろっと書いてみます。

今回はAndroidです。 Android開発やったことない人には、ちんぷんかんぷんかと思いますのでご注意。

AndroidStudioでプラグインを作る

もはやAndroid開発でEclipseなんて使ってるのは相当アレなエンジニアもしくはアレな案件に従事している方だと思いますが、いちおう断りを入れておくと今回はAndroidStudio(2.1.2)を使います。

https://developer.android.com/studio/index.html

新規プロジェクトを作る

まずは普通にプロジェクトを作りましょう。Activityはあってもなくてもいいです。

ライブラリ用モジュールの作成

プロジェクトを作成したら、メニューから新規モジュールを作成します。 モジュールの種別選択でAndroid Libraryを選択してください。

f:id:sugar_affordance:20160714122247p:plain

ここではモジュール名をDialog-Pluginとしておきます。

Unityからアクセスするクラスを作成する

ライブラリ用モジュールにクラスを作成します。

package jp.co.test.dialog_plugin;

import android.app.AlertDialog;
import android.content.Context;

public class NativeDialog {

    static public void showMessage(Context context, String title, String message) {

        new AlertDialog.Builder(context)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("YES, YES, YES!", null)
                .setNegativeButton("...No?", null)
                .show();
    }
}

呼び出したいメソッドはstaticとして定義しておきます。 Context渡してるけどUnityからどうやって受け取るねん! という心配はご無用なのでまんじゅうでも食っててください。

次にGradleスクリプトを実行してライブラリをビルドします。 Gradleペインを開き、dialog-pluginモジュールのTasks > build > assembleをダブルクリックします。

f:id:sugar_affordance:20160714122353p:plain

すると、プロジェクトフォルダ内のdialog-plugin/build/outputs/aar フォルダにdialog-plugin-debug.aar、dialog-plugin-release.aarというファイルが作成されます。これがライブラリの本体です。
どっち使ってもいいんですが、今回は dialog-plugin-debug.aar を使っておきます。

ライブラリの拡張子について

アセットなどで拡張子が .jar になっているファイルを見たことがあると思いますが、今回作成したのは .aar です。 aarはAndroid用のライブラリ用の拡張子で、リソースファイルやManifestファイルも内包されています。 Unityはjarだけでなくaar形式にも対応していて、こっちのほうがあつかいが簡単です。

Unityからプラグインを呼び出す

とりあえず適当にプロジェクトを作りましょう。

aarを配置する

Assets/Plugins/Android という構造でフォルダを作り、Androidフォルダの中に dialog-plugin-debug.aar を置きます。

f:id:sugar_affordance:20160714122433p:plain

これだけでJavaのメソッドを呼び出す準備は完了です。

あ、プロジェクト設定はAndroidにSwitchPlatformしておきましょう。

プラグインを呼び出す

Unity側のソースは以下のようにします。

using UnityEngine;
using System.Collections;

public class AndroidDialogTest : MonoBehaviour {

    void Start () {
        ShowDialog ();
    }
    
    void Update () {
    
    }

    void ShowDialog() {
        #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,
                "おっさんの主張",
                "もうやってられまへーん"
            );
        }));
        #endif
    }

}

プラグインのクラスにアクセスするには AndroidJavaClassを使用します。引数には作成したクラスのパッケージ名を与えます。 Unityアプリを実行しているActivityやContextを取得する際も同様です。

ビルドして端末にインストール

USBで端末接続してBuild & Run すれば、みっともないダイアログが出るのでやってみよう!

注意するエラー

minSdkVersionがあってない

下のようなエラーが出る場合、minSdkVersionの設定が合ってないです。

Error: [Temp/StagingArea/AndroidManifest-main.xml:12, /xxxxxxx/AndroidManifest.xml:3] Main manifest has <uses-sdk android:minSdkVersion='9'> but library uses minSdkVersion='19'

AndroidStudioのdialog-pluginのbuild.gradleを開くと、

applyplugin:'com.android.library'

android{
  compileSdkVersion23
  buildToolsVersion"23.0.3"

  defaultConfig{
    minSdkVersion19
    targetSdkVersion23
    versionCode1
    versionName"1.0"
  }
...

こんな感じになってると思いますが、minSdkVersion 19 となってますね。

ひるがえってUnityでBuildSettingsからPlayerSettingsを開くと、

f:id:sugar_affordance:20160714122514p:plain

デフォルト値が API Level9になっています。 ここをプラグインより大きい値にする必要があります。

なんか知らんが動かん

logcat でエラーが出てないかチェックしましょう。 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() とか出てる場合、UIスレッドで動かないといけないので注意。 今回のソースの

context.Call ("runOnUiThread"new AndroidJavaRunnable(() => {

の部分ね。

あとインターネット接続してるのにManifestにパーミッション書いてないとかね。

    <uses-permission android:name="android.permission.INTERNET" />

を追加しろよね!

iPhoneは?

いつか書く。

・参考 http://docs.unity3d.com/ja/current/ScriptReference/AndroidJavaClass.html

Amazon.co.jpアソシエイト