2017.07.21

Unityで作ったARコンテンツを既存のネイティブアプリに組み込む方法について


はじめに

こんにちは。次世代システム研究室の B.M.Kです。

近年、スマホの進化とともにグーグル、マイクロソフト、フェイスブック、アップルといった巨大テクノロジー企業がAR分野に参入し、優れたAR技術、プラットフォームを紹介したことでAR市場への関心が高まっています。ARを実際に応用する時、スタンドアロンタイプのARアプリだけではなく、既存のネイティブアプリにARを組み込むニーズも多くあります。今回はUnityで作ったARコンテンツを既存のネイティブアプリ(Android版)に組み込む方法について紹介したいと思います。既存のネイティブアプリ(iOS版)にARを組み込む方法については別の機会でまとめて共有します。

準備

組み込む流れ

  • UnityVuforia SDKを用いた、ARアプリの準備
  • Android Studio プロジェクトへエクスポート
  • 使用するUnityバージョンで入り口のActivityを変更
  • Androidライブラリの作成
  • 既存のネイティブアプリへのインポート
  • リンキングの設定
  • Manifestファイルをマージ
  • 組み込むARアプリを起動

1. UnityとVuforiaSDKを用いた、ARアプリの準備

Vuforiaとは開発時のライセンスを無償で提供している名高いARライブラリです。ネイティブAPIUnity向けのSDKをサポートしています。VuforiaUnityを用いた、ARアプリの作り方は以下のリンクを参考して下さい。

Unity3Dと無料開発ライセンス付きライブラリ「Vuforia」でAR家具カタログの作り方
 今回は任意なロゴの画像とUnityちゃんという無償の3Dモデルを使用して、シンプルなARアプリを用意しました。


2.Android Studio プロジェクトをエクスポート

 Unity上に作られたプロジェクト(C#又は JavaScriptプロジェクト)を他のプラットフォームのプロジェクト(Android Studio又はXcode)にエクスポートすることができます。以下の手順でAndroid Studioプロジェクトにエクスポートします。
UnityメインメニューからFile > Build Settingsを選択し、 Build Settings ダイアログボックスを開きます.
・使うUnityシーンを追加してから、Androidプラットフォームを切り替えて、「Google Android Project」のところにチェックを入れ「Export」を行います。

export

 

 

 

 

 

 

 

 

 

 

 

 

エクスポートされたAndroid Studioプロジェクトは以下のようになります。

 

project_before_import_new

 

エクスポートされたAndroid Studio プロジェクトにてGradleファイル等がないため、Android Studioから「Open Project」を使用せず、「Import Exist Project」を使ってAndroid Studioにインポートします。そうすると、ビルドするための必須なGradleファイルを自動的に生成と設定されます。

インポートする時に以下のオプションにチェックを入れます。

gradle_check
 

 

 

 

 

 

 

 

インポートされたプロジェクトの構成は以下のようになります。

project_after_import_new

 

 

 

 

 

 

 

3. 使用するUnityバージョンで入り口のActivityを変更

 UnityからエクスポートされたAndroidプロジェクトには もっとも重要なアクティビティは次の3つのアクティビティです。
  •  UnityPlayerActivity
  • UnityPlayerNativeActivity
  • VideoPlayer

Unityバージョン5.4.X前を使った場合、Unity上ARアプリの入り口のアクティビティがUnityPlayerNativeActivityでありましたが、Unityバージョン5.4.X以降を使った場合はUnityPlayerNativeActivityをサポートしなくなったため、ManifestファイルにてUnityPlayerNativeActivityを削除してUnityPlayerActivityを使わなければなりません。


<activity android:label="@string/app_name" android:screenOrientation="portrait" android:launchMode="singleTask" 
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" 
android:name="gmo.repeater.ar.UnityPlayerNativeActivity">
また、後ほど、組み込むARアプリを起動するために入り口のアクティビティの intent-fileractionタグを以下のように変更ししておきます。
<activity android:label="@string/app_name" android:screenOrientation="portrait" android:launchMode="singleTask" 
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" 
android:name="gmo.repeater.ar.UnityPlayerActivity">
<intent-filter>
  <action android:name="gmo.repeater.ar.UnityPlayerActivity" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

4. Androidライブラリの作成

Android ライブラリは、構造上が Android アプリ モジュールと同じです。ソースコード、リソース ファイル、Android マニフェストなど、アプリのビルドに必要なものはすべて含めることができます。ただし Android ライブラリをコンパイルすると、端末で実行する APK ではなく、 AAR(Android Archive)ファイルになります。JAR ファイルとは異なり、AAR ファイルには Android リソースとマニフェスト ファイルを含めることができるため、Java クラスやメソッド以外に、レイアウトやドローアブルといった共有リソースにもバンドルできます。

次の手順でAARファイルを作ります。
  • Unityからエクスポートされたアプリ モジュールのgradle ファイルを開き、「application」から「library」に変更します。
apply plugin: 'com.android.library'
  • エクスポートされたプロジェクトのgradle ファイルにて、Gradle Android Pluginバージョンを以下のように設定します。
dependencies {
 classpath 'com.android.tools.build:gradle:2.1.3'
}
  • Gradle-wrapper.propertiesファイルを開き、Gradleバージョンを設定します。
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
Gradle Android pluginGradleバージョンとの関係は以下のリンクを参考して下さい。
  • [Sync Project with Gradle Files] で、Android ライブラリ(AARファイル)を生成します。
aar_file_new

 

 

 

 

 

 

 

 

 

AARファイルが正常に生成された場合、AARファイルの構成は以下のようになります。

aar_structure_new

 

 

 

 

 

5. 既存のネイティブアプリにインポート

次のいずれかの方法でライブラリをプロジェクトに追加します。
  • コンパイルした AARファイルのみをインポート
    1. [File] > [New Module]を選択
    2. [Import .JAR/.AAR PackageAARファイルのみ(例:app-debug.aarファイル)をインポートします。
  • ライブラリ モジュールをプロジェクトにインポート
    1. [File] > [New] > [Import Module]を選択
    2. ライブラリ モジュールのディレクトリの場所を入力し、[Finish] をクリックします。
この場合、ライブラリ モジュールがプロジェクトにコピーされ、ライブラリ コードを編集できるようになります. 今回のデモで[Import .JAR/.AAR Package]を使ってAARファイルをインポートしました。

 

6. リンキングの設定

既存アプリのプロジェクトのgradleファイルのにて AARファイル名(今回は“app-debug”) を追加します。
include ':app', ':app-debug'
既存アプリのapp モジュールのgradle ファイルに以下のdependenciesを追加します。
dependencies {
 compile project(":app-debug")
 }
[Sync Project with Gradle Files] でリンキングの設定が正常であるかどうかを確認して次のステップを進みます。

 

7. Manifestファイルをマージする

Unityから生成されたManifestファイルを既存アプリのManifestファイルにマージします。uses-feature, uses-permission, uses-library, meta-data, activityタグ等の全てがマージする対象になりますが既存アプリのManifestファイルにて同じタグがあれば、そのタグのマージが不要です。基本的に以下の情報をマージします。
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="22" />
 <uses-feature android:name="android.hardware.camera" />
 <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.CAMERA" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:debuggable="false" android:isGame="true" android:banner="@drawable/app_banner">
 <activity android:label="@string/app_name" android:screenOrientation="portrait" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" android:name="gmo.repeater.ar.UnityPlayerActivity">
 <intent-filter>
 <action android:name="gmo.repeater.ar.UnityPlayerActivity" />
 <category android:name="android.intent.category.DEFAULT" />
 </intent-filter>
 <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
 <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
 </activity>
 <activity android:name="com.unity3d.player.VideoPlayer" android:label="@string/app_name" android:screenOrientation="portrait" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
 </activity>
 <uses-library android:name="com.ti.s3d" android:required="false" />
 <uses-library android:name="com.osterhoutgroup.api.ext" android:required="false" />
 </application>
 <uses-feature android:glEsVersion="0x00020000" />
 <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
 <uses-feature android:name="android.hardware.camera.front" android:required="false" />
 <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
 <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
 <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
また、マージする時にandroid: themeと android: iconタグにて衝突が起こるので 以下の処理をManifestファイルに入れたら解決できます。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools">
<application
  tools:replace="android:theme, icon"
主なマージ作業が終わりました。次は織り込んだActivityを起動します。

 

8. 組み込むARアプリを起動する

上記のステップ3にて織り込んだARアプリの入り口のアクテビティ(UnityPlayerActivity)の inten-filteractionを指定しておりましたので 以下のintentを設定すれば、織り込んだARアプリを起動することができます。
Intent intent = new Intent ("gmo.repeater.ar.UnityPlayerActivity");
startActivity(intent);
既存アプリに織り込んだARはこんな感じです。



 

まとめ

今回、既存のネイティブアプリ(Android版)にARを組み込む方法を紹介しました。いくつかの設定が必要となりますが組み込む先のアプリと独立性が高いARコンテンツならば、AARファイルを利用することをお勧めします。

次世代システム研究室では、アプリケーション開発や設計を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ募集職種一覧からご応募をお願いします。