[Unity] Android NativePluginの実装の仕方

# はじめに
Unityで使用するNativePluginのタスクがあったのでとりあえずテストでサンプルを作成してみました。
ここでは、UnityでAndroidのNativeアラートを表示させるまでの忘却録です。

## 環境
macOS Catalina: 10.15.7
Unity 2018.4.19f
Android Studio 4.0.1

## Android Studioでプロジェクトを作成

今回は「AndroidStudio4.0.1」で作成していきます。
![android001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/b27ed595-5ee7-4a67-ebd3-cbaedaff4da0.png)

「Select a Project Template」で「No Activity」を選択
![android002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/a0bb70e2-948b-e8e6-3992-551fd530f87d.png)

Projectの概要を決めていきます。「Package name」はサンプルなので適当です。言語は「Java」を選択しました。
![android003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/ba3ba0d3-3058-2826-2dc2-67599f279d15.png)

## ライブラリ用モジュールを作成する

「File」→「New」→「NewModule」を選択
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/b4442aa2-eaf8-99c8-2807-39f62d6d9afc.png)

「Select a Module Type」で「Android Library」を選択
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/0760c184-23b1-8f4e-9d82-73e52a55d929.png)

「Module name」もサンプルなので適当にそのままにしました。
![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/ceed8fc2-0283-9a9d-80ce-0daa6cbc327a.png)

左上にあるプルダウンから「Android」を選択しておきます。
![android004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/5359b565-89b0-5b3c-f07a-854ab551db9c.png)

「mylibrary」が出来てます。
![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/3b85cc3f-7a1e-8a07-5a97-be956e6770d3.png)

## Plugin開発には不必要なAppディレクトリを削除する

「File」→「Project Structure」を選択
![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/8f15aa9b-078c-3ac4-e871-8aead24e41f5.png)

左サイドバーの「Modules」を選択して「app」を選択。赤丸の「-」で削除します。
![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/1ba847a9-8641-1f19-50c3-030a238d30b8.png)

「Remove Module」で削除確認されますが、「Yes」です。
![011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/8a51b3a0-3def-6c38-d1c0-8b9d8a9d9d1e.png)

## Unity機能をAndroidから使用する準備
Android側からUnityのクラスを認識するために「jar」ファイルをインポートする必要があります。
主に`UnitySendMessage`を使う時などです。アラートであればこの部分は必要ありません。
> Android 用に開発されたプラグインを使用して、Unity の外部で作成された Java や C++ コードを C# スクリプトから呼び出しすることができます。これにより、他の方法では Unity で使用できない OS の呼び出しやサードパーティのコードライブラリなどの機能にアクセスできます。Unity によるプラグインの使用方法の詳細については、プラグイン のドキュメントを参照してください。
以下のページでは、Android プロジェクトで使用する独自のプラグインを作成する手順を説明します。これらのページの情報は、Unity のネイティブプラグインの作成方法をすでに理解していることを前提としています。ネイティブプラグインとその使用の詳細については、ネイティブプラグイン のドキュメントを参照してください。
https://docs.unity3d.com/ja/current/Manual/PluginsForAndroid.html

場所はUnityがインストールされてるディレクトリにあります。
ファイル名: **classes.jar**
下記は、UnityHubを使用していた場合の格納場所です。

```
/Applications/Unity/Hub/Editor/2018.4.19f1/PlaybackEngines/AndroidPlayer/Variations/il2cpp/Release/Classes/classes.jar
```

Androidプロジェクトの「libs」ディレクトリへ「classes.jar」をコピーします。
![012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/75aee8a8-ffe0-7081-bd74-3331e0abb214.png)

## Gradleの設定からclasses.jarを外す
Gradleの設定からclasses.jarを外さないと、出力されるaarファイルに含まれてしまいUnityのビルド時にエラーが出てしまうので外さないといけません。ということで、「build.gradle」を編集します。
![013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/575a07d3-579b-462d-28c9-61127566ba5d.png)
下記、箇所を変更。また、追記します。

``` gradle:build.gradle
// 26行目
NG： implementation fileTree(dir: "libs", include: ["*.jar"])
↓
OK: compileOnly fileTree(dir: 'libs', include: ['classes.jar'])

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

完成形は下記。右上に出ている「SyncNow」を押下して完了
![014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/73ee0933-e7fa-f786-d349-d86a10421a0d.png)

## Unityで呼び出すNativeAlertDialogのサンプル
該当箇所からClassを作成します。
![ 2021-09-06 16.36.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/955bb44d-fa74-bb48-7768-ea30df64b5c5.png)
![ 2021-09-06 16.37.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/c1d82849-b872-9ab0-6d97-492b6567b671.png)
![ 2021-09-06 16.37.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/8103555f-bf79-5d82-2e6f-043ff8c87315.png)
![ 2021-09-06 17.04.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/cd83872a-171f-4fbf-9b5c-d9211ad8b527.png)


該当コード

```java:AndroidNativeDialog.java
package jp.co.test.mylibrary;

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

public class AndroidNativeDialog {
    static public void showNativeDialog(Context context, String title, String message) {
        new AlertDialog.Builder(context)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("はい", null)
                .setNegativeButton("いいえ", null)
                .show();
    }
}
```

https://developer.android.com/guide/topics/ui/dialogs?hl=ja

https://qiita.com/suzukihr/items/8973527ebb8bb35f6bb8

## ビルド
画面右側に「Gradle」のアイコンがありますので、設定画面を表示します。
![ 2021-09-06 17.06.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/0108f2a3-1a02-04b8-471e-27ca3d2368ae.png)

「mylibrary」→「Tasks」→「build」→「assemble」をダブルクリックでビルドが始まります。
![ 2021-09-06 17.07.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/7f06b731-e2d2-f970-1e84-bd9f6fe57fe2.png)

成功すると「BUILD SUCCESSFUL in 時間」が表示されます。
![ 2021-09-06 17.07.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/46ee2622-595a-41dc-ff24-a527746aa24f.png)

## aarの場所
左上から「Project」を選択し、「mylibrary」→「build」→「outputs」→「aar」の中にあります。
![ 2021-09-06 17.19.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/a0c3703c-5187-77b4-cc21-81ecff33d033.png)

該当のファイルから「Reveal in Finder」でFinderが開いてくれます。
![ 2021-09-06 17.55.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/cb92dc28-70fb-7858-c435-45cea12dec67.png)

## aarをUnityプロジェクトへ配置する
UnityプロジェクトをAndroidにSwitchPlatformします。
該当のaarは「Assets」→「Plugins」→「Android」のディレクトリを無ければ作成して配置します。
![ 2021-09-06 17.59.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/331bb0c1-9cce-c2dd-55fc-6b048d53d3a3.png)

## Unity側の対応(呼び出し方法)サンプル
呼び出す際に「AndroidJavaClass」、「AndroidJavaObject」を使います。
サンプルでは、ShowNativeDialog()をButtonEventで使用しました。

```c#:ButtonView.cs
using UnityEngine;

public class ButtonView : MonoBehaviour
{
    public void ShowNativeDialog() {
        #if UNITY_ANDROID
        AndroidJavaClass nativeDialog = new AndroidJavaClass ("jp.co.test.mylibrary.AndroidNativeDialog");
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject context  = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

        context.Call ("runOnUiThread", new AndroidJavaRunnable(() => {
            nativeDialog.CallStatic (
                "showNativeDialog",
                context,
                "タイトル",
                "本文テキスト"
            );
        }));
        #elif UNITY_EDITOR
            UnityEngine.Debug.Log("On Click!");
        #endif
    }
}
```

### サンプルフォルダ構成
![ 2021-09-07 15.02.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/ab0badb9-21cf-475d-21d8-433495ac87ab.png)

### Unity配置
ボタンを押下するとアラートダイヤログを表示
![ 2021-11-17 18.09.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/027695b3-bdaa-ccab-d53a-64dfe9da4fdd.png)


ビルドして実機で確認します。
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/060c96f9-091c-165a-3f9a-746ea8db6758.gif)




## 成果物
[ここにある](https://github.com/atsutama2/NativePluginTest)プロジェクトをダウンロードしてもらい、Androidでビルドしてもらえれば実機確認可能です。
`File`→`BuildSettings`→`Build`でapkが出来ます。

![ 2021-11-17 18.31.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/94ba94c9-876c-e7bb-7cf5-69fc4c370c0a.png)

実機インストールについては`adb`コマンドが使えれば出来ます。

https://techgrowup.net/2021/05/25/adb-tips/

https://github.com/atsutama2/NativePluginTest