【Unity】【C#】プロジェクト内で Android(Java)プラグインをビルドする 
2018/10/11 Thu [edit]
Unity 2018.2 の新機能として『Unity プロジェクト内で .java および .cpp のソースファイルがプラグインとして使用可能に』と書いてあったので試してみた。
私も Androidネイティブプラグインをアセットストアで配布しているが、どちらかというとオールインワン的なプラグインとなってしまったので、これ以上追加すると使わない機能の分もファイルサイズが増えてしまうので、どうしようかと考えていたところだ(笑)。
なのでタイミング的にもちょうど良かったかも知れない。Unity 2018.2 から導入された、プロジェクトに Java を内包して Grandle でビルドする方法を使えば、1つ1つの欲しい機能だけを追加することもできる。特にスマホのようなメモリもストレージも容量が小さいデバイスは、無駄にファイルサイズを増やさないで済むので重宝されそうだ。
やってみた感想は、とても簡単で特につまづくことも無かったが、Java のコードに手を加える分にはやはり Android Studio で編集した方が良いかも知れない(どのみち Android SDK はインストールしなくてはならないし…)。また、単純にコードやインポートのチェック、エラーのデバッグも必要だしね。ただ、既に動作確認とれている Java コードなら、Android Studio を開かないで多少の手直しなどはできるから、かなり便利だ(笑)。
とりあえず今回は Android ビルドの環境が整ってる状態でのコード作成やビルドの方法となるので、環境構築が必要な場合は、資料となる記事などを掲載しておくので、参考にして欲しい。また、Android Studio でコードを書く際での参照設定もついでに書いておこう。これらはバージョンによって大幅に仕様変更される可能性が高いので、できれば常に最新の情報を検索して確認するようにして欲しい。
(Android ビルドのための環境構築など)
・[Unity初心者Tips]SDKはここでした!AndroidでBuildする方法2018の10月版
・Android Studio のインストール
(※) Unity 2018.2.1f1 / Android Studio 3.1.3 / Windows10(x64) / Galaxy S7 Edge (Android 8.0) で確認
■Android プラグインを Java で書く
Java のコードは何らかのテキストエディタでも Android Studio を使っても良い。ただ Android Studio で書く場合は多少、参照設定など環境構築が必要なので、それらは「Android Studio で Unity プラグインを作る際の参照設定など」を参照して欲しい。
とりあえず今回は Android の トースト機能(戻値なし)と、int型の値を受け取る実験として、プラグインからビルドバージョンを取得する(戻値あり)プラグインを書いてみよう。
●プラグイン定義:Java (Android) 側のコード(AndroidPluginSample.java)
package com.sample.myapplication;
import android.os.Build;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
public class AndroidPluginSample {
//トースト用コード
public void ShowToast(String message, boolean longDuration) {
Toast.makeText(UnityPlayer.currentActivity,
message,
longDuration ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT)
.show();
}
//ビルドバージョン取得用コード
public int GetBuildVersion() {
return Build.VERSION.SDK_INT;
}
}
Java コード自体の解説は割愛するので、必要あればググって欲しい(難しくはないのですぐに理解できると思う)。今回この2つを用意したのは、戻値ありのメソッドと戻値なしのメソッドを試してみたかったからだ。実際これらができれば、プラグインでやりたいことは大抵できると思う。ちなみに Unity のシステムと Android のシステムは別物として動いてると考えて良いので、データの受け渡しをする際には基本的にプリミティブ型中心となる。複雑なパラメタを持つクラスなどをやりとりしたい場合は、共通のプリミティブ型で作ったクラスを定義するとか、JSON などにして文字列型で渡すのが良いだろう。
ちなみに私が提供しているプラグインは JSON でやりとりしてる。本当はプリミティブ型だけでやりとりした方が高速だとは思うが、パラメタを増やしたり、仕様変更したりするときなどの保守が大変になってしまうのと、何より JSON に関しては Unity でも Android でも簡単に利用できるビルトイン機能があるので、非常に楽に扱えるメリットがあるからだ(JSON はただの文字列型なので、データの加工・流用がしやすい)。高速性や保守性を考えて、どちらを使うかを選択するのも良いだろう。
この Javaコードが書けたら、Unity のプロジェクトビューで Assets 直下に「Plugins/Android」フォルダを作ろう。ここに Java ソースを置くことにより、Unity がビルドする際に一緒にコンパイルされる(Build System が「Gradle」のときのみ)。

■Unity から Android プラグインを利用する C# コード
上記の Java コードを書いて、プラグイン用フォルダに配置したら、次に Unity から利用する C# コードを書いてみよう。
今回の例では Unity 上で UI ボタンを置き、それを押すことにより、トースト表示とビルドバージョンの取得をしている。UI などのコールバック設定方法などは以前の記事にまとめてあるので参照して欲しい。簡単に言えば、Button の場合はインペクタで「On Click()」に以下のコードの「OnClick()」を登録すれば良いだけだ。面倒なら UI を使わずに「Start()」から直接「OnClick()」を呼ぶようにしても良い(ただし起動時にいきなりだと、確認しずらいと思うが(笑))。
・UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録
●プラグイン呼び出し:C# (Unity) 側のコード(JavaPluginTest.cs)
using UnityEngine;
public class JavaPluginTest : MonoBehaviour {
// Use this for initialization
private void Start () {
//OnClick(); //ここから呼んでも良い
}
const string PLUGIN_PACKAGE_NAME = "com.sample.myapplication.AndroidPluginSample"; //ここは Java で作った package 名と class 名に合わせる
//Button.OnClick などから呼ぶ
public void OnClick()
{
//ビルドバージョンの取得テスト
int buildVersion = 0;
using (var JavaPlugin = new AndroidJavaObject(PLUGIN_PACKAGE_NAME))
{
buildVersion = JavaPlugin.Call<int>("GetBuildVersion");
}
//トーストの表示テスト
using (var JavaPlugin = new AndroidJavaObject(PLUGIN_PACKAGE_NAME))
{
JavaPlugin.Call("ShowToast", "テストだよん\nBuild Version : " + buildVersion, true); //buildVersion が取得できなかったときは 0 となる
}
}
}
注意点は定数「PLUGIN_PACKAGE_NAME」(名前は任意)で先に作った Java の package 名と class 名を繋いでフルパスで指定する点だ。このパッケージ名はアプリ自体のパッケージ名(Bundle Identifer)とは別でも構わない。他のプラグインを利用することも考えて、自作するときには世界で唯一の名前にしておこう("com.sample.myapplication" は良くない例(笑))。この Java での package(パッケージ名)とは C# で言う namespace に近いものなので、ユニークにしておけば、同じクラス名があっても大丈夫だ(なので絶対パスで指定する必要がある)。Java の場合パッケージ名の区切り文字(ドット:".")はフォルダ名と同義になるので、実際にパス名となる(ドット:"." を "\" や "/" に置き換えたパスに格納されている。C# の場合はパスになってなくても良い)。
あとは「Build Settings...」にテストするシーンを入れて「Build System」を「Gradle」にしてビルド(Unity2017以降はデフォルト)するだけだ。実機で確認してみよう。まだ環境構築ができてない場合は、以下の資料を参考にして欲しい。
(Android ビルドのための環境構築など)
・[Unity初心者Tips]SDKはここでした!AndroidでBuildする方法2018の10月版
・Android Studio のインストール

●Build System は「Gradle」にする(Unity2017 以降はデフォルト)

●実機ではボタンを押すとビルドバージョンがトーストで表示される
■Android Studio で Unity プラグインを作る際の参照設定など
意外と Android プラグイン作成でつまづくのは Android Studio の環境構築(特に Gradle)だ。この辺りは導入しているバージョンによって違うので、上手く行かなかったら、自分が使っているバージョンも含めてググって欲しい。ここではあくまでも私が上手く行った設定方法を書いておく。特に Gradle に関しては 2.x と 3.x では書き方も違うので、Android Studio を 2.x から 3.x にアップデートしたときなどは、いっそのこと環境を再構築した方が良いかも知れない(私も大量のエラーやアップデートで不具合が出たため、新規インストールから再構築した経験がある)。
また、私の環境では、SDKのビルドツールのバージョンなども Android 7.0 まで対応の場合は Android SDK Platform-Tools 27.x.x で、Android 8.0 以降対応では Android SDK Platform-Tools 28.x.x でビルドしないと上手く行かなかった。組み合わせもあるかも知れないので、原因不明のビルドエラーが多発するなら、その辺りも見直した方が良いだろう。
Android Studio で Unity 用のプラグインを作成する場合、インポート文「import com.unity3d.player.UnityPlayer」が必要になる(参照設定してない場合、エラーが出てると思う)。これはインストールした Unity の以下のフォルダに「classes.jar」があるので、Android プロジェクト内の「libs」フォルダにコピーし、参照設定すれば良い。そこまでやってみよう。
(公式から抜粋)
1.(Windows の場合)「(Unityをインストールしたフォルダ)\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Classes」をエクスプローラで開くと「classes.jar」がある。それを右クリックで「コピー」し、Android Studio に戻り、プロジェクト内の「libs」フォルダに右クリックで「Paste」する。

2.メニューから「File>Project Structure...」を開き、左のペインで現在のプロジェクト(Modules)を選択し、「Dependencies」タブに切り替えたら、右にある「+」ボタンをクリックし、「Jar Dependency」を選択する。
3.「Select Path」ダイアログが出たら、先ほどコピーした「libs/classes.jar」を選択し、OKを押す。
4.これで Unity(プレイヤー)への参照設定が追加されたので、「Scope」を「Complie only」にしておく(※今回はあまり必要ないが、Android Studio で aar などをビルドしたくなったとき、あった方が良い)。
一応、今回のように Unity のみでビルドする際には上記まででもOKだが、Android Studio で aar などをビルドしたくなったときは Gradle 設定に以下の文を入れておくと良い。

●build.gradle (モジュールごとにあるので注意)
・・・(略)・・・
dependencies {
//implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation fileTree(include: ['*.jar'], exclude: ['classes.jar'], dir: 'libs')
・・・(略)・・・
}
「dependencies」部分に元からあった「implementation fileTree(include: ['*.jar'], dir: 'libs')」をコメントアウトして、「exclude: ['classes.jar']」を入れた文に書き換えておこう。これはビルドする際「classes.jar」自体は含めないという設定だ。開発中は参照する必要があるが、リリースする際には Unity 本体に含まれているので、この除外設定がないと2重にライブラリがインクルードされる(ファイルサイズも無駄に増える)。ただし、Android Studio でビルドせず、Unity だけでビルドするなら、この設定は必要ない(あくまでも念のため)。
この辺りはバージョンによって書き方も変わってるようなので、できればその都度確認した方が良いだろう。
Android Studio で Java コードを書いた際は、プロジェクト内で作ったクラスを右クリックで「Copy」し、これを Unity プロジェクトの「Assets/Plugins/Android/」フォルダ以下にペーストすれば良い。あとは「Build Settings...」で「Build System」を「Gradle」にすれば一緒にビルドされる。aar にビルドする必要はないので、とても楽だ。試してみよう。
実際にビルドする際には、マニフェストファイル(AndroidManifest.xml)の編集が必要になることもあるので、その辺りの資料は以下を参照して欲しい。
・Android ビルドをもう少し詳しく
・Android アプリでパーミッション(権限)要求をする
・Android マニフェスト
(関連記事)
【Unity】Firebase のプッシュ通知と FantomPlugin の共存(Firebase と他のプラグインの共存方法)
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Android アプリでパーミッション(権限)要求をする
- 関連記事
トラックバック
トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/311-047e29af
この記事にトラックバックする(FC2ブログユーザー)
| h o m e |