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

ほげほげ(仮)

仮死状態

AndroidStudioを使ってUnityとAndroidの連携

Unity Android

概要

UnityとAndroidを連携するには色々やり方あると思いますが、AndroidStudioを使ってaarを作成し連携させます。

色々調べてたらEclipseとjarを使った連携をよく見かけましたが、ADTがもう開発終わってしまうので今後はAndroidStudioを使うべきでしょう。(An update on Eclipse Android Developer Tools | Android Developers Blog

このやり方は探しても見つからなかったので、手順的なものを簡単にまとめておきます。

環境

Unityプロジェクト準備

普通に作ります。

パッケージ名とminバージョン等を設定しておきます。

ここでは例としてパッケージ名はcom.sample.samplegameとしました。

f:id:STAR_ZERO:20150710000207p:plain

フォルダ作成

プラグイン

Androidプラグイン用にAssets/Plugins/Androidを作成しておきます。

AndroidStudio

AndroidStudioのプロジェクトを配置する用のフォルダを作成します。

Gitで管理対象にしたいので下のようにプロジェクト直下にフォルダを作ります。ここではAndroidProjectという名前にしましたが好きなようにしても問題無いです。

<project root>
├── AndroidProject  ← 作る
├── Assets
├── Library
├── ProjectSettings
└── Temp

AndroidStudioプロジェクト

プロジェクト作成

ここで本来であれば直接ライブラリプロジェクトを作りたいのですが、現時点ではできないようなので一度アプリ用のモジュールを作ります。

先ほど作ったAndroidProjectフォルダにに普通にAndroidStudioでプロジェクトを作ります。

ここで作ったアプリモジュールを直接使用することは無いのでパッケージ名などは適当で良いです。確認用に使う可能性もあるのでUnityで設定したものとは別のものにしたほうがいいかもです。

モジュール作成

メニューのFile > New > New Moduleを選択します。

分かりにくいのですが、More MoudlesのリストにあるAndroid Libraryを選択します。

f:id:STAR_ZERO:20150709232612p:plain

モジュール名はlibとかにします。ここで重要なのはパッケージ名をUnityで設定したものと同じものにしないことです。

この例ですとcom.sample.samplegame.libという感じに末尾にlibを付与しました。

f:id:STAR_ZERO:20150709232646p:plain

Activityは必要じゃないのでAdd No Activityを選択します。

モジュールを作成すると下のような感じの構成になると思います。

f:id:STAR_ZERO:20150709232717p:plain

Unityのjarを配置

Unity.app/Contents/PlaybackEngines/AndroidPlayer/release/bin/classes.jarを先ほど作ったモジュールのlibsフォルダへコピーしてきます。

Gradle設定

モジュール内のbuild.gradleに下記を追加します。

UnityからAndroidでビルドした時にUnity側が用意するjarと先ほどコピーしたjarがカブってしまうのでビルド時に除外するようにします。

android.libraryVariants.all { variant ->
    variant.outputs.each { output ->
        output.packageLibrary.exclude('libs/classes.jar')
    }
}

aar作成

まだ特にコード書いてないですが、先にaarを作成する手順を。

GradleのassembleReleaseタスクを実行するとモジュール内のbuild/outputs/aar/lib-release.aarが作成されます。

この作成されたaarをUnity側のAssets/Plugins/Androidへ配置すると連携できるようになります。

ただ毎回コピペするのも面倒なのでGradleタスクを作ります。

task exportAar(type: Copy, dependsOn: assembleRelease)  {
    from('build/outputs/aar/')
    into('../../../Assets/Plugins/Android/')
    include('lib-release.aar')
    rename('lib-release.aar', 'samplegame-lib.aar')
}

この作ったexportAarタスクを実行するとビルドとコピー、リネームをしてくれます。

このタスクはAndroid側のコード等を変更したら毎回実行する必要があります。

連携実装

サンプルでUnityからAndroidのToast表示処理を呼び出してみます。このあたりの詳細はマニュアルとググってください。

Android

引数をとってToast表示してます。Unityから呼び出したときはUIスレッドではないのでrunOnUiThreadを使ってます。

package com.sample.samplegame.lib;

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

import com.unity3d.player.UnityPlayer;

public class NativePlugin {
    public static void showToast(final String message) {
        final Activity activity = UnityPlayer.currentActivity;
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(activity, message, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

クラスを作ったらGradleのタスクを実行してaarを更新しておきます。これ忘れたら動かないので。

Unity

とりあえずテキトーにGUIのボタンから呼び出す感じです。GUIイベントの設定方法等は省略します。

using UnityEngine;

public class Sample : MonoBehaviour
{
    public void OnClickButton ()
    {
        using (AndroidJavaClass javaCalss = new AndroidJavaClass ("com.sample.samplegame.lib.NativePlugin")) {
            javaCalss.CallStatic ("showToast", "Test");
        }
    }
}

実行

UnityからBuild & Runで実行して試してみます。

補足

Manifestファイル

aarにはManifestファイルが含まれるのですが、ここにはアプリ全体に関わるようなものを記述しないようにしないでください。

例えばandroid.intent.action.MAINandroid.intent.category.LAUNCHERをもったActivityを書いてしまうと、Unity側が生成するManifest側と合わせて2つ存在することになるので、アプリが2つインストールされてる感じになったりします。

またパッケージ名もUnity側と同じものを付けないようにします。

ManifestをカスタマイズするときはAssets/Plugins/AndroidAndroidManifest.xmlを作ってそれを編集しましょう。詳細はマニュアル等を見てください。

res

AndroidStudioのresディレクトリにあるものもaarに含まれるのでコードから普通に使用できます。

appモジュール

最初にAndroidプロジェクトを作った時に残ってるappモジュールは確認用として使うことが出来ます。

appモジュールのbuild.gradleで依存関係を設定すれば普通に呼び出せますので。

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
    compile project(':lib') // ←追加
}

今回のToastを表示するものを確認するにはappモジュールのActivity等に下のように記述すれば通常のAndroidアプリのように確認できます。UnityPlayer.currentActivityは普通のstatic変数なので普通に設定すれば問題無いです。

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 追記
        UnityPlayer.currentActivity = this;
        NativePlugin.showToast("Text");
    }
    
    //...
}

ライブラリ

Gradleで設定した依存関係はそのままだと反映されません。

また逆にlibsフォルダに配置したjar等は自動でaarに含まれることになるので、Assets/Plugins/Androidに同じjarがある場合などは除外する設定を追加する必要があります。

これについては次回時間があるときにまとめます。

追記: まとめました UnityのAndroidでライブラリを使う - ほげほげ(仮)

まとめ

だいぶ面倒な感じ見えますが、一度設定すればそこまで手間ではないと思います。