ぐーるらいふ

底辺。

【Unity】Android Nativeプラグイン開発 最小構成でなるべくわかりやすくまとめた

Androidでネイティブプラグイン

Androidでネイティブプラグイン開発を行う時の作業手順をまとめてメモしておきます。

環境

使用した環境は以下になります。

そして、最小構成で作成します。
aarを使わず、より不要な物をそぎ落としたjarで組み込みます。

なるべく処理に不要な物は排除し、本当に処理を行うのに必要なものは
何なのか?という事に着目してまとめてます。
なるべく、わかりやすく。Step By Stepで。

Android Studioを使ってUnityプラグインを作ろう

手順1 プロジェクトを作成

Android Studioを立ち上げ、新規プロジェクトを「Add No Activity」で作成します。

f:id:ghoul_life:20190126020326p:plain:w300
f:id:ghoul_life:20190126020559p:plain:w300

手順2 ライブラリモジュールを作成

プロジェクトが出来たら、ライブラリモジュールを作成します。

Android Studioの上部メニューバーからFile > New > New Module
そして、「Android Library」を選択して作成します。

f:id:ghoul_life:20190126020926p:plain
f:id:ghoul_life:20190126021255p:plain:w300
f:id:ghoul_life:20190126021041p:plain:w300

手順3 必要ないファイルの削除

ライブラリモジュール以外は必要ないため、
作成したプロジェクトフォルダを開き、最初に作られたappを削除します。

f:id:ghoul_life:20190126021732p:plain:w300

そしてsetting.gradleからもappを消します。

include ':app' ':unitypluginsamplelibrary'
->
include ':unitypluginsamplelibrary'

f:id:ghoul_life:20190126021919p:plain:w300

手順4 Unityクラスライブラリの追加

AndroidでNative連携Pluginを作る時、AndroidからUnityの機能を呼びたい事があります。
そういった機能をAndroidから使えるように、Unityが用意しているAndroid用クラスライブラリをPlugin側に組み込む必要があります。
例えば、Unity HubでUnity2018.3.2f1の場合はここにあります。

C:\Program Files\Unity\Hub\Editor\2018.3.2f1\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

これをモジュールのlibsの中にコピーして配置します。

f:id:ghoul_life:20190126022258p:plain:w300

手順5 ビルドスクリプトの修正

ビルドスクリプト(モジュールの直下にあるbuild.gradle)を以下のように整理修正します。
(compileSdkVersionなどは各環境に合わせて下さい)

apply plugin: 'com.android.library'

android {
    compileSdkVersion 27

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    compileOnly fileTree(dir: 'libs', include: 'classes.jar')
}

// buildしたjarをカレントに持ってきてリネーム
task createJarFile(type: Copy) {
    // 環境によって出力先がよく変わるみたい?intermediates-jarsとかもあるらしい
    from('build/intermediates/packaged-classes/release/')
    into('.')
    include('classes.jar')
    rename('classes.jar', 'UnityPluginSample.jar')
}
createJarFile.dependsOn(build)

新規追加したタスク「createJarFile」はUnityに組み込むjarをビルド後に抜き出し、リネームするタスクです。こういうのを作ると楽になります。

実はこの辺りでちょっと困ったことがあったので、その件についてまとめました。

ghoul-life.hatenablog.com

aarを使わないこの記事の方針では実はここまでしなくても良かったりします。
興味があれば一読してみてください。

手順6 configurationの設定

Android StudioからcreateJarFileタスクを実行出来るように構成を設定します。
Android StudioのEdit ConfigurationsからGradleを選択して、以下を参考に設定してください。

+ボタン > Add New Configuration > Gradle
Name : 自由に
Gradle Project : プロジェクトフォルダを選択
Tasks : createJarFileと入力

f:id:ghoul_life:20190126023556p:plain:w300
f:id:ghoul_life:20190126023708p:plain:w300

手順7 テスト用ファイルの削除

本来は必要であるべきと思われるのですが、最小構成なので、ここでは省きます。
モジュール作成時に自動で追加されるTestコードを削除します。

f:id:ghoul_life:20190126024030p:plain:w300

手順8 実際に使用するコードを記述する

ここまで来てようやっとコードがかけます。長い。
ソースファイルを新規追加し、以下のようにコードを記述します。
手順4でライブラリを正しくlibsの下に配置していて、手順5でgradleの設定が出来ていれば
com.unity3d.playerパッケージが使えるようになるはずで、エラーが出ないと思われます。
(エラーが出るときはその辺りを見直すとよい)

package com.example.unitypluginsamplelibrary;

import com.unity3d.player.UnityPlayer;
import java.util.Random;

public class HelloAndroidNativePlugin {

    public static void Execute()
    {
        Random r = new Random();
        UnityPlayer.UnitySendMessage("AndroidNativeManager" , "FromAndroid" , "Hello Unity Android Plugin. Rand." + r.nextInt());
    }
}

手順9 ビルドしてJarを作成する

Build VariantsをReleaseにして、ConfigureをcreateJarFileに合わせ、RunすればOKです。
BUILD SUCCESSと出れば、正常にプラグインが作成出来ています。

f:id:ghoul_life:20190126024718p:plain:w300

これでAndroid側の作業は完了です。

UnityでAndroid Pluginを組み込む

こちらはぐっと簡単です。

手順1 作成したプラグインを配置

Assets/Plugins/Android

以下に配置します。上の手順ならjarファイルをそこにポンと置けばOKです。

f:id:ghoul_life:20190126025305p:plain

手順2 プラグインの機能を使用するスクリプトを作成

組み込んだプラグインの機能を使うスクリプトを記述します。
AndroidJavaClassでクラスを指定し、Callで呼びたい関数を指定すればOKです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class AndroidNativeManager : MonoBehaviour
{
    [SerializeField] Text _androidMessageText;

    public static readonly string ANDROID_NATIVE_PLUGIN_CLASS = "com.example.unitypluginsamplelibrary.HelloAndroidNativePlugin";

    // Start is called before the first frame update
    void Start()
    {
        ResetMessage();
    }

    public void CallAndroidPlugin()
    {
        using (AndroidJavaClass androidJavaClass = new AndroidJavaClass(ANDROID_NATIVE_PLUGIN_CLASS))
        {
            androidJavaClass.CallStatic("Execute");
        }
    }

    public void ResetMessage()
    {
        _androidMessageText.text = "";
    }

    public void FromAndroid(string message)
    {
        _androidMessageText.text = message;
    }
}

apkを作成し、実機で動かしてみる

実際にapkをビルドして、それを実機で動かしてテストします。
自分はAndroid Emuratorで実行しました。

f:id:ghoul_life:20190126030157g:plain

Unity -> Android -> Unity
と問題なく処理が動いているのを確認できました。