以前Windows向けのNative Pluginに関する記事を書きましたが、UnityではAndroidでも勿論Native Pluginが使えます。
事前準備
Android向けNative Pluginを作るにあたって事前にAndroid向け開発環境を入れておく必要があります。
JDKとAndroid StudioとAndroid NDKです。(※URL変わってるかもしれません…)
Android SDKとNDKをインストールする際はスペースや日本語が含まれたパスは使わないようにしてください。
× C:\Program Files\Android-dev\~
○ C:\Android-dev\~
プロジェクト作る
まずAndroid Studioでプロジェクトを作ります。
まずFile → New → New Projectを選択します。
次にApplication Name、Company Domain、Project Locationの3つを聞かれますので好きにつけます。
- Application Name
- アプリ名です。なんでもいいです。
- Company Domain
- Androidアプリに設定する他の人とかぶらないIDです。公開する予定がないのでしたらなんでもいいです。大体は自身のホームページのURLを逆にしたものが設定されます。(例: jp.ne.sakura.cfm-art)
- Project Location
- プロジェクトの保存先です。スペースや日本語が入らないように注意してください。
次に対応するアンドロイドのバージョン等を聞かれますが、これも好きなものを選択してください。
最後にテンプレートの使用を聞かれますが、今回はNativeを利用するだけなのでAdd no Activityを選択してください。
これでプロジェクトが生成されます。
パスの設定をする
プロジェクトが出来たらパスを設定します。
File → Project Structureを選択します。
それぞれインストールした場所を設定します。
メイクファイル作る
Android Studioでは最近NDKも対応しだしたのですが、初期設定ではエラーが発生して使えません。
対応としてメイクファイル(build.gradle)を編集する必要があります。
まず、プロジェクト名側のbuild.gradleを編集します。
※build.gradleはプロジェクトとappの2種類あります。間違わないように注意してください。
Android Studioのバージョンやプロジェクトの設定で細かな部分で内容が違いますので適宜読み替えてください。
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.0.0-beta6' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
最初はこのようになっているので下記のように変更します。
変更点をハイライトしています。
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle-experimental:0.6.0-beta5' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
次にapp側のbuild.gradleを編集します。
apply plugin: 'com.android.application' android { compileSdkVersion 22 buildToolsVersion "22.0.1" defaultConfig { applicationId "jp.ne.sakura.cfm_art.myapplication" minSdkVersion 19 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:22.2.1' }
これを下記のように変更します。
apply plugin: 'com.android.model.application' model { android { compileSdkVersion 22 buildToolsVersion "22.0.1" defaultConfig { applicationId "jp.ne.sakura.cfm_art.myapplication" minSdkVersion.apiLevel 19 targetSdkVersion.apiLevel 22 versionCode 1 versionName "1.0" buildConfigFields { create() { type "int" name "VALUE" value "1" } } } buildTypes { release { minifyEnabled false proguardFiles.add(file("proguard-rules.pro")) } } ndk { moduleName "プラグイン名" } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:22.2.1' }
プラグイン名は好きな名前を設定してください。
エラーが出る場合は記述が間違っていますのでもう一度見比べてみてください。特にbuildConfigFields{}とndk{}の挿入個所を間違えないように気を付けてください。
これでNative Pluginを作成する環境が整いました。
この設定を行うとAndroid Studioのメニューからアプリのバージョン設定等が行えなくなります。
変更が必要な場合は自分でbuild.gradleを適切に編集する必要が出てきます。
Unity側の準備
Unityのプラグインを入れる場所を用意しておきます。
上図のようにPlugins\Android\libsフォルダーを生成しておきます。
ソースを試しに書いてみる
では、試しに何かを書きます。
srcのmainの下にjniフォルダーを生成します。
jniフォルダー作ったらその中にC++ sourceを作成します。
中身はこのようにします。
// // Created by art on 2016/03/06. // extern "C" { int Sample( int n ) { return n * 2; } }
※extern “C”が必須です。Unity側ではこのSample関数を呼び出すようにしたいと思います。
では、このプロジェクトをMakeします。
これでプラグインが生成されています。
ビルドが終わったらプロジェクトフォルダ内の「app\build\intermediates\binaries\debug\lib」内の「armeabi-v7a」と「x86」フォルダーをコピーして、UnityのPlugins\Android\libsの下にペーストします。
※リリースの場合は「app\build\intermediates\binaries\release\lib」からコピーしてください。
UnityからNative Plugin内の関数を呼び出す
using UnityEngine; using System.Runtime.InteropServices; public class NativeSample : MonoBehaviour { #if UNITY_EDITOR // Editorではプラグイン読み込めないので別で用意しておく private static int Sample( int v ) { return 0; } #else [DllImport( "originalplugin" )] private static extern int Sample( int v ); #endif void OnGUI() { int value = Sample( 1 ); GUILayout.Box( value.ToString() ); } }
Native Pluginの関数を呼び出す為には
[DllImport( “プラグイン名” )] private static extern 返り値 関数名( 引数 );
の形式で記述する事で利用できるようになります。
これをAndroidの実機で実行するとプラグインのSample関数が呼び出されて左上に「2」が表示されます。(Editorではプラグインが利用されないので0が表示されます)