Unity で ARKit & ARCore AR開発環境のマルチプラットーフォーム(iOS & Android)対応

[ARKit](https://developer.apple.com/jp/arkit/)と[ARCore](https://developers.google.com/ar/)を共通のシーンで両方の環境に対応したビルドを作成できる、Unityのライブラリを作成しました。こちらにて公開しているのでご活用してください。
https://github.com/TakuKobayashi/UnityARKitAndARCoreCommon
unitypackageにしたものをご希望でしたら、こちらからダウンロードしてください。
https://github.com/TakuKobayashi/UnityARKitAndARCoreCommon/releases

また、上記ライブラリの中にそれぞれ、[ARKit](https://developer.apple.com/jp/arkit/)、[ARCore](https://developers.google.com/ar/)が入っていますが、双方とも頻繁にバージョンアップされます。本ライブラリでもバージョンアップはしていきますが、バージョンアップが必要な場合は適宜バージョンアップをお願いします。(バージョンアップする場合の注意事項は下記に記載します)

なお、[ARCore](https://developers.google.com/ar/)単体についての詳しい説明などはこちらをご覧ください。
[ARCore 取扱説明書](https://qiita.com/taptappun/items/a5337d29a43d5d673c7f)

# 最新のAR(一般論)
## AR
ARとは拡張現実(Augmented Reality)という意味で<font color="#FF0000">人が知覚する現実環境をコンピュータにより拡張する技術、およびコンピュータにより拡張された現実環境そのもの</font>です。
【参考】 [拡張現実](https://ja.wikipedia.org/wiki/%E6%8B%A1%E5%BC%B5%E7%8F%BE%E5%AE%9F)

人間の視覚 → カメラ
人間の聴覚 → マイク 

がそれぞれコンピュータにおける入力であり、大半が視覚(カメラ)に映し出されたものに合わせて拡張したものがARと呼ばれます。

近年、技術発展が著しいXR(VR/MR/AR)の内、ARはスマートフォン単体で利用可能で、追加のハードウェアがいらない点も特徴の一つです。
![XR.png](https://qiita-image-store.s3.amazonaws.com/0/72596/db391a6a-385c-d119-69e4-68cc6634e36a.png)

## これまでのAR
[ARKit](https://developer.apple.com/jp/arkit/)、[ARCore](https://developers.google.com/ar/)が出る以前にも、AR技術を利用したものは存在しました。これまでのARは大きく分けると2種類に分類されます。

 ・ 特徴となる画像(マーカー)を用意し、その画像を検出してものを出す。(例:QRコードリーダー, [Vuforia](https://vuforia.com/) など)
![Vuforia-Logo-OLx2a896-728x195.png](https://qiita-image-store.s3.amazonaws.com/0/72596/4f933d86-b132-b555-0c76-de5e897544e8.png)

 ・ カメラ以外のセンサーで検出したものを元にカメラ画面の上に検出してものを出す。(例:[セカイカメラ](https://ja.wikipedia.org/wiki/%E3%82%BB%E3%82%AB%E3%82%A4%E3%82%AB%E3%83%A1%E3%83%A9)、[ポケモンGo](http://www.pokemongo.jp/))

![st_photo1.png](https://qiita-image-store.s3.amazonaws.com/0/72596/5df5f22f-7314-6da6-5e3f-10b27a363ebc.png)　<img width="300" alt="22d360544d9588d16b57fa6a185551a4.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/72596/a21ab17a-36ea-3908-8466-135173ebae16.jpeg">

## 最新のARとは?
[ARKit](https://developer.apple.com/jp/arkit/)、[ARCore](https://developers.google.com/ar/)をはじめとした最新のARでは以下の特徴を活かした開発をすることが可能です。

 * 端末のセンサーを駆使した空間認識
 * マーカーとなる画像が不要

また最新のARではVRの技術も応用しているため、「実際の現実空間を認識している」ことが一部可能となっています。
例えば、以下のように、実際の地面を検出し、そこにものやキャラクターを表示していくといったことが可能となっています。
![ezgif-3-c10ddc3c08.gif](https://qiita-image-store.s3.amazonaws.com/0/72596/b4c87768-a69a-3816-ed6b-ad15a108c985.gif)

# [ARKit](https://developer.apple.com/jp/arkit/)、[ARCore](https://developers.google.com/ar/)
[ARKit](https://developer.apple.com/jp/arkit/)とは、AppleによるiOS向けのARアプリ開発フレームワークです。Androidでは利用することができません。
[ARKit](https://developer.apple.com/jp/arkit/)のAndroid版が[ARCore](https://developers.google.com/ar/)です。[ARKit](https://developer.apple.com/jp/arkit/)で実現できることの多くは[ARCore](https://developers.google.com/ar/)でも実現できます。[ARCore](https://developers.google.com/ar/)はiOSでは利用することができません。(GoogleはTangoプロジェクトにてARの研究開発をしていました。Tangoプロジェクトを[ARCore](https://developers.google.com/ar/)に統合したため、[ARKit](https://developer.apple.com/jp/arkit/)の後追いではないではありません)
[ARKit](https://developer.apple.com/jp/arkit/)で具体的にどんなことができそうなのかということは[こちら](https://www.gaprot.jp/gaprot-x-chogiken/xr/arkit_position_tracking)を参照してください。([ARCore](https://developers.google.com/ar/)とできることの違いはありますが大体同様のことができます。)

[ARCore](https://developers.google.com/ar/)の導入方法など、詳しい説明はこちらを参照してください。
[ARCore 取扱説明書](https://qiita.com/taptappun/items/a5337d29a43d5d673c7f)

以降では[ARKit](https://developer.apple.com/jp/arkit/)について中心的に紹介します。

## [ARKit](https://developer.apple.com/jp/arkit/)の開発環境とライブラリのダウンロード先
|開発環境|ライブラリ|
|---|---|
|[XCode](https://developer.apple.com/jp/develop/)|[ARKit](https://developer.apple.com/jp/arkit/)|
|[Unity](https://unity3d.com/jp)|[Unity-ARKit-Plugin](https://bitbucket.org/Unity-Technologies/unity-arkit-plugin)|
|[Unreal Engine4](https://www.unrealengine.com/ja/features)|[UE4ARKit](https://github.com/ludenio/UE4ARKit)|
|web|[arkit-web](https://github.com/Stinkstudios/arkit-web), [WebARonARKit](https://github.com/google-ar/WebARonARKit)|

以降にUnityへの導入方法を記述します。
UE4への導入についてはこちらを参照してください。

 * [アンリアル エンジン 4.18 がリリースされました](https://www.unrealengine.com/ja/blog/unreal-engine-4-18-released)
 * [猫でも分かるUE4を使ったARコンテンツ作り方 初級編 ver 1.0.0](https://www.slideshare.net/EpicGamesJapan/ue4ar-ver-100)

## [ARKit](https://developer.apple.com/jp/arkit/)をUnityに導入
基本的にUnity ARKit PluginのunitypackageをUnityのプロジェクトに導入するだけです。
サンプルなどはExamplesの中にあるsceneをいくつか開いて、実行してみてください。Unity ARKit PluginはAssetStoreとBitbucketの両方があり、どちらからでもダウンロードし、インストールすることができます。
<font color="#FF0000"> ※下記に記載しますが、Unity ARKit Pluginのインストールの仕様の関係上、
[ARCore](https://developers.google.com/ar/)と両方に対応した環境を構築する場合、注意が必要な部分があります。</font>

 * [Unity ARKit Plugin (Asset Store)](https://assetstore.unity.com/packages/essentials/tutorial-projects/unity-arkit-plugin-92515)
 * [Unity-ARKit-Plugin (Bitbucket)](https://bitbucket.org/Unity-Technologies/unity-arkit-plugin)

また、その他詳しい説明などはこちらなどを参考にしてください。
[UnityでiOSのARKitを動かす手順
](https://qiita.com/arumani/items/aac7372a171e441e1f16)

## 課題
現状、[ARKit](https://developer.apple.com/jp/arkit/)、[ARCore](https://developers.google.com/ar/)ではそれぞれiOS、Androidで対応しているプラットフォームが分かれています。[ARKit](https://developer.apple.com/jp/arkit/)、[ARCore](https://developers.google.com/ar/)ともにUnityにて開発可能ですが、プラットフォームごとにそれぞれ全て個別に対応する必要があります。今回、この開発のしにくさを極力解消するために共通のSceneで[ARKit](https://developer.apple.com/jp/arkit/)、[ARCore](https://developers.google.com/ar/)両方の環境に対応できるものを開発できるようなライブラリを作りました。

# マルチプラットフォーム開発の手引き
今回、作成したUnityライブラリ([UnityARKitAndARCoreCommon](https://github.com/TakuKobayashi/UnityARKitAndARCoreCommon))
こちらの導入と開発方法をベースに解説していきます。

## まず動かしてみる
iOS, Androidそれぞれ、Switch Platformするところまで、以下の手順のように共通で行います。

1. [こちら](https://github.com/TakuKobayashi/UnityARKitAndARCoreCommon/releases) から最新のunitypackageをダウンロードしてきて展開する。
2. File->Build Settingsを選択して、Build Settingsを開く

![BuildSettings.png](https://qiita-image-store.s3.amazonaws.com/0/72596/e9d366ec-f34f-15d8-d9fa-2bd90822d6ff.png)

Build Settingsを開いた後はiOS, AndroidそれぞれのプラットフォームにてBuildを行います。

### iOS
Build Settingsを開いた後、iOSのプラットフォームに切り替え、ビルドし、実機にインストールします。
なお、iOSの場合、実機(端末)の他に[Xcode](https://developer.apple.com/jp/xcode/)のダウンロード・インストールや[Apple Developer Program](https://developer.apple.com/programs/jp/)に登録し、iOSの実機にインストールするための諸々の事前準備が必要になります。やり方などは以下なども参考にしてください。

 * [Xcode8.xでのiPhone実機デバッグメモ](https://qiita.com/DKN915/items/7a2ce97f3758e2daf486)
 * [Appleの開発者登録をする, iOSアプリ作成準備](https://i-app-tec.com/ios/developer-registration.html)
 * [iOS開発ガイド](https://developer.apple.com/jp/documentation/Xcode/Conceptual/ios_development_workflow/#000-Introduction/introduction.html)

![BuildSettingsiOS.png](https://qiita-image-store.s3.amazonaws.com/0/72596/d4762446-388f-aa35-8605-681a2c65ff0a.png)

1. Platformの中の「iOS」を選択して、「Switch Platform」ボタンを押す。
2. Platformが変更されたら、「Player Settings...」ボタンを押してPlayerSettingsを開く

![iOSUnityBuild.png](https://qiita-image-store.s3.amazonaws.com/0/72596/b9d97188-ff5a-6418-03c4-d5c585a95df7.png)

1. PlayerSettingsを開いたら、「Bundle Identifier」を[Apple Developer Program](https://developer.apple.com/programs/jp/)に登録したもの(Xcodeでのビルドが可能なもの)に変更する(後で設定することもできます)
2. 「Camera Usage Description」に何かしら文字列が入っていることを確認する。これは実機にビルドした時にカメラを使用することの許可を促すものです。ここで入力したものはその許可を促すダイアログのタイトルとして表示されます。(「Camera Usage Description」を空欄にするとカメラの仕様許可をも求めるダイアログが出ず、カメラを使うこともできません)
3. Build Settingsに戻り、「Build」ボタンを押します。しばらくするとXcodeプロジェクトが出力されます。

![iOSBuild.png](https://qiita-image-store.s3.amazonaws.com/0/72596/7c8981f8-8999-7c0c-3452-97dd93eebbd8.png)

Xcodeプロジェクトが出来上がったら、Unity-iPhone.xcodeprojを選択し、XcodeプロジェクトをXcodeにて開きます。

![XcodeProject.png](https://qiita-image-store.s3.amazonaws.com/0/72596/7d06d532-23fe-f82a-cf40-f1aa0edeab80.png)

1. プロジェクトのプロジェクト設定を開く。
2. General > Identity > Bundle Identifier が[Apple Developer Program](https://developer.apple.com/programs/jp/)に登録し、ビルドして端末にインストールすることができる値が設定されているか確認する
3. General > Signing > Team で任意Teamを選択([Apple Developer Program](https://developer.apple.com/programs/jp/)にビルドしてインストールする端末が登録されているTeam)
4. ビルドする対象の端末を選択肢、▶︎ボタンを押してビルドする。(ビルドできたらそのまま実機にインストールされます)

上記ARSceneは、iOSとAndroid共通で使用することができるSceneです。ARKitにのみに対応したSceneはARKitSceneになります。


### Android
Build Settingsを開いた後、Android端末で実行するためにビルドします。

![BuildSettingsAndroid.png](https://qiita-image-store.s3.amazonaws.com/0/72596/2734de3b-631c-98ab-39d8-60cfd0dcad8a.png)

1. Platformの中の「Android」を選択して、「Switch Platform」ボタンを押す。
2. Platformが「Android」に切り替わったら、「Scenes In Build」の中の「ARScene」にチェックが入っていることを確認して、「Build」または「Build And Run」ボタンを押してビルドします。「Build」ボタンを押した場合、しばらくすると[apkファイル](https://ja.wikipedia.org/wiki/APK_(%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%BD%A2%E5%BC%8F))ができあがります。「Build And Run」ボタンを押した場合は実機のAndroid端末とつながっていればそのまま[apkファイル](https://ja.wikipedia.org/wiki/APK_(%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%BD%A2%E5%BC%8F))をAndroid端末にインストールし、実行します。

上記ARSceneは、iOSとAndroid共通で使用することができるSceneです。ARCoreにのみに対応したSceneはARCoreSceneになります。

## どうなっているの?
基本的にARCoreのサンプルプロジェクトである、<font color="9467bd">HelloAR.scene(GoogleARCore/Examples/HelloAR/HelloAR.scene)</font>で行われていることを基準にARKitでも同様のことができるようにしています。ARKit, ARCoreそれぞれで共通できる処理をまとめ、共通できない部分はそれぞれで分離するようにしました。以降では具体的な処理の中身について説明します。

## どうやって開発していけばいい?
このプロジェクトではARKitで使用するものを<font color="FF7F0e">ARKitController.prefab</font>で, ARCoreで使用するものを<font color="FF7F0e">ARCoreController.prefab</font>でそれぞれ使用できるようにし,<font color="FF7F0e">SwitchARController.prefab</font>ではPlatformに応じたそれぞれのprefabを用いるようにしています。
![SwitchARController.png](https://qiita-image-store.s3.amazonaws.com/0/72596/79d6d072-2b1f-f8f4-b7a9-0da385100584.png)

### ARKitにあって、ARCoreにはない機能の処理を実装したい
![ARKitController.png](https://qiita-image-store.s3.amazonaws.com/0/72596/16f18780-d135-1865-7927-33e133d4522d.png)


<font color="FF7F0e">ARKitController.prefab</font>には<font color="17becf">ARKitController.cs</font>のスクリプトを適用しています。<font color="17becf">ARKitController.cs</font>内にARKitにのみ適用した処理を記述していくことで、ARKit専用の処理を実装することができます。また、ARKitController.prefabに設定していくことで、ARKitでのみ使えるパラメータを設定することができます。

### ARCoreにあって、ARKitにはない機能の処理を実装したい
![ARCoreController.png](https://qiita-image-store.s3.amazonaws.com/0/72596/4444f397-8c9b-0dfb-8abf-38cd4fc6628c.png)


<font color="FF7F0e">ARCoreController.prefab</font>には<font color="17becf">ARCoreController.cs</font>のスクリプトを適用しています。

### ARKit, ARCore両方ともに対応する処理を実装したい
ARCore, ARKit両方ともに共通して使うことができるような処理や設定情報は全て、<font color="17becf">ARControllerBase.cs</font>に記述しています。(<font color="17becf">ARKitController.cs</font>, <font color="17becf">ARCoreController.cs</font>ともに<font color="17becf">ARControllerBase.cs</font>を継承しています。)
<font color="17becf">ARControllerBase.cs</font>に処理を記述していくことで、ARCore, ARKit両方に対応されます。
prefabなどの設定はそれぞれに設定できるようにしています。

## [ARKit](https://developers.google.com/ar/), [ARCore](https://developers.google.com/ar/)それぞれのバージョンアップ
<font color="#FF0000">このライブラリでは[ARKit](https://developers.google.com/ar/), [ARCore](https://developers.google.com/ar/)、それぞれ個別にバージョンをアップする方法と同様の方法でバージョンアップできるように作っています。</font>
しかし特にARKitのライブラリの仕様の関係上、バージョンアップする場合、以下の点を留意してバージョンを上げる必要があります。

### ProjectSettings.assetとEditorBuildSettings.assetは更新しない
![CautionARKit.png](https://qiita-image-store.s3.amazonaws.com/0/72596/44c1443e-76fb-2da1-f56d-afc1c91a6b02.png)

Unity-ARKit-Pluginをインストールする場合、環境設定で設定した変数も更新してしまいます。そのため、上記のように、該当ファイルのチェックを外し、更新しないようにする必要があります。

#### ProjectSettings.assetとは?
![projectSettings.png](https://qiita-image-store.s3.amazonaws.com/0/72596/9c01e691-b8ac-c753-f9fe-0c89693e25dd.png)
上記、プロジェクトの設定に関すること全般の情報です。

#### EditorBuildSettings.assetとは?
![EditorBuildSettings.png](https://qiita-image-store.s3.amazonaws.com/0/72596/906bfa85-c694-50c6-4fa4-87ed7145983e.png)
上記、ビルドする時に指定するSceneの情報を登録している部分です。

### もし更新しちゃったら?
![RecoverAndroidSettings.png](https://qiita-image-store.s3.amazonaws.com/0/72596/ea9fe5b2-d9b7-eb6a-597e-968d1685bb45.png)
ProjectSettings.assetにおいては特にAndroidの環境設定において、上記の印をつけた箇所の修正をするようにし、
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f37323539362f62313230616365642d626534392d326439612d333761312d3635623532396166336162352e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/72596/72d45e61-68a0-dc34-42be-5448a6e77c83.png)
ARCore Supportedにチェックを入れる。

EditorBuildSettings.assetについては各自、ビルドに含めたいsceneを追加していってください。


## そもそもなんでUnityなの?
ARKit, ARCoreともにUnity(UE4でもですが)で開発する場合であっても、実機にビルドしないと実行結果を確認することができません。Unityの▶︎を押しEditor上での動作の確認は基本的できません。(ARKitにある、ARKitRemoteの機能を使えば確認はできますがその場合であっても実機にBuildする必要はあります。)
しかし、Unity(UE4もですが)最大の強みは3Dファイルの読み込み、計算、制御が簡単にできることにあります。3Dについて説明はこちらを参照。
[3D入門](https://www.slideshare.net/takukobayashi560/3d-70392050)
![3d-1-638.jpg](https://qiita-image-store.s3.amazonaws.com/0/72596/b2255875-7a87-24dd-a4e3-fac03aa0cf5a.jpeg)

# まとめ
今時のARについての説明とARKit,ARCoreの両方に対応したライブラリの紹介をしました。
今時のARを実装するにあたり、どうしてもARKit,ARCoreのiOS, Android両方の環境に対応したものを手軽に作りたいというニーズがあったのでライブラリを作成しました。
今回、可能な限り簡単に開発でき、共通のソースコードで開発できるようにしました。
また、ARKit,ARCoreそれぞれのアップデートが簡単にできるように作ってみました。
もしよかったら使ってください。また、issue, Pull Reqeust,あとスターもいただけたらと思います。

# 関連記事
 * [ARCore 取扱説明書](https://qiita.com/taptappun/items/a5337d29a43d5d673c7f)
 * [Unity で 3Dモデル を取り扱う上で単調になりがちな作業をまとめて処理してくれるツールを作成しました](https://qiita.com/taptappun/items/30914c590ef5b75944a6)