イケメンテックラボでエンジニアをしている寺林です。
今回はUnity2019のARFoundationというUnityが提供しているAR開発パッケージを導入して遊んでみたのでその導入方法を紹介します!
ARFoundationとは
ARFoundationはUnityが現在開発しているAR開発用のフレームワークです。
特徴としては、ARKitとARCoreのマルチプラットフォームARを簡単に作ることができます。
イケメンテックラボブログでは過去にARKitとARCoreの導入方法を紹介しました。
iPhoneでリッチなAR体験!ARKitをUnityで使ってみた
これらを使ってARアプリの開発も勿論できるのですが、
ARKitを使った場合はiOSでのみ動作するアプリに、 ARCoreを使った場合はAndroidでのみ動くアプリに、と言ったハードウェアの制約があり、AndroidとiOS両方で動くアプリを作る場合はARCoreとARKitで別々の実装をする必要がありました。
これは開発する上で結構不便ですよね。
それを解決するために、Unityが現在開発をしているのがARFoundationです。
ARFoundationを使って作ったアプリはiOSにビルドするとARKitで、
AndroidにビルドするとARCoreで動作するようになります。
ARKitとARCoreを同じ実装で扱えるようになるので別々で実装するのと比べてかなり工数は減らすことができますし、ARFoundationのアップデートだけを拾い続ければARKitやARCoreの仕様変更などを考慮しなくても良くなるのが利点になります。
ただ、ARCoreが現時点で対応していないARKitのEnvironmentTexturing(環境の映り込み)を使いたい!みたいなケースだと一工夫必要になるのかな、といった感じです。
現在開発中(Previewバージョン)なのですが触ってみたところかなり簡単に作ることができましたので手順を紹介します!
※今回の記事ではUnityのPreview(開発中)パッケージを使っているため、記事執筆時の仕様から今後変更が加わったり手順が変わったりする可能性があります。最新情報などはUnityのパッケージリファレンスやフォーラムなどをご覧ください。
必要な環境
今回は以下の環境で実装をしました。
・Unity2019.1.8f1
・ARKit XR Plugin(2.2.0-preview.1)
・ARCore XR Plugin(2.1.0)
・ARFoundation 2.2.0-preview.2
ARKit XR Plugin、ARCore XR Plugin、ARFoundationは記事内で導入します。
Unityは2019を落とした上でAndroid、iOSのビルド環境はあるものとして進めます。
またARFoundationは内部でARCore、ARKitを使っているので、
ARCore、ARKitに対応した端末が必要になります。
記事内ではiOSはiPhoneXS(iOS12)
AndroidはHuawei P20で検証してます。
準備
まずはいつも通りUnityのプロジェクトを作りましょう!
今回はARFoundationTestというプロジェクト名にしました。

まずはパッケージの導入をしましょう。
Unityが起動したらWindow->Package Managerを選択しましょう。

Previewパッケージはデフフォルトでは非表示になっているため、普通にパッケージマネージャを開いただけでは一覧には出てきませんのでお気をつけください。
Advancedをクリックし、Show Preview Packagesをクリックします。

すると安定してないパッケージだけど表示してもいいですか?というウインドウが出てくるのでYesをクリックしましょう。これでパッケージリストに表示されるようになります。

ではパッケージを入れていきましょう。まずは各プラットフォームのXRPluginを導入します。
ARCore XR Plugin、 ARKit XR Pluginを入れましょう。一応こちらはビルドするプラットフォームのものが入ってれば問題ないそうですが、何かしら問題が起きると怖いですし、両方入れないでいる事で起きるメリットもないので両方入れちゃいましょう。
右下のInstallをクリックで入ります。


最後にARFoundation 本体を入れましょう。

これでARFoundationを使う準備はできました。
ARFoundationのシーンを作ってみる
まずはプロジェクトを作った時に開かれてるSampleSceneにあるオブジェクトを全て消しましょう。(Main Camera 、DirectionalLightとか)

ヒエラルキー上で右クリックし、XR->ARSessionと
XR->AR SessionOriginの二つを生成します。


するとこんな感じになると思います。
ARSessionの方がARのライフサイクルを管理している感じで、
ARSessionOriginの方がカメラとかAR空間上での制御などを見ているイメージです。(おそらく。)

これでひとまず最低限のものは揃います。シンプルですね。
試しにビルドしてみる
一回Android向けにビルドしてみましょう(ビルドが早いので…)
BundleIDを指定して、ビルドしてみると、まぁ想像はしてましたがエラーが出ました。


ARCoreはVulkan(描画API)に対応してないよ、というエラーと、
MinimumSDKは24以上にしてね、というエラーです。直しましょう。
PlayerSettingsのMinimum API LevelをAndroid7.0 Nougatに、

Graphics APIのところ、Vulkanを選択し、−ボタンをクリックしましょう。

OpenGLES3が一番上に来ればOKです。
OpenGLES2.0でも動くとは思いますがARCore対応端末でOpenGLES3に対応してない端末、多分ないと思うのでこれで問題ないと思います。

これでビルドしたところ無事起動しました。
このようにカメラの映像が表示されていれば正常に動いています!

iOSのビルドも試してみたところ、案の定エラー。直していきましょう。

カメラ利用の文言が空だよというエラーとアーキテクチャがARM64じゃないと動かないよというエラーです。
BuildSettngsからPlayer Settingsを開き、OtherSettingsの中にある
Camera Usage Descriptionに文言を入れましょう。

そのちょっと下にあるArchitectureをARM64にしましょう。

これでUnityのビルドは通ったのですがXCodeでビルドした時にエラーが発生してしまいました。

ARKit3.0の対応をARFoundationの最新版で入れている為、XCodeのバージョンが10だとこのエラーが出てしまうようです。
ARFoundationのリポジトリに書いてありました。

この記事を書いている現時点(2019/6/25)ではまだiOS13もXCode11も正式版リリースされていない為、エラーが出るのは当然といえば当然ですね。
なので解決策としてはXCode 11betaを入れるか、ARFoundationをダウングレードさせるかのどちらかになります。
今回は後者(ARFoundationをダウングレードさせる)にしました。Beta版入れるの結構面倒なので…。(iOS13端末も用意しないといけないため)
AR Foundationを2.1.0とARKit XR Pluginを2.1.0にダウングレードさせたところ、無事ビルドが通るようになりました!


この時期ならではのレアケースな感じがしますが、もし遭遇した方はダウングレードを試してみてください!
平面を表示させてみよう
さて、カメラの映像がアプリで表示できることは確認できました。
次に平面の表示をさせてみましょう。 ARCoreやARKitの時にも出ていた、認識した平面を視覚的にわかるようにするものです。
AR Session Originを選択肢、ARPlane ManagerをAdd Componentします。

ARPlaneManagerのPlane Prefabにあるものが表示されるようになります。
このPrefabを作りましょう。

ヒエラルキーで右クリックし、XR->AR Default Planeを選びます。

作成したらそのAR Default PlaneをそのままPrefab化しましょう。

最後にPlane Prefabに指定してやればこれで平面が表示されるようになります。

ビルドして実行するとこのように、平面を検知した部分が表示されます。とても簡単ですね。
線の色などはAR Default Planeコンポーネントのパラメータたちをいじってやると変更もできます。

点群(PointCloud)を表示させてみよう
ARCore、ARKitと同じように特徴点を表示させてみましょう。
AR SessionOriginにARPoint Cloud Managerを追加します。

PointCloud Prefabに設定したオブジェクトが表示されます。さっきのPlane Managerさんとほとんど同じですね!わかりやすい!

さっきと同じように今度はAR Default PointCloudを作成してPrefab化して…

指定してやりましょう。これで準備はOK。ビルドして実機でみてみましょう。

ちょっと気持ち悪いですが点群が表示されました!ほとんど同じやり方で出来るのは嬉しいですね!もちろんこの点の見た目も変更できます。

平面上にオブジェクトを配置する
最後に、この検知している平面の上にオブジェクトを配置してみましょう!
AR Session OriginにARRaycast Managerを追加します。
これを使って平面がどこにあるのか調べることができます。

次にコードを書きましょう。今回はARManager.csというファイルを作成し、以下のようなコードを書きました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
public class ARManager : MonoBehaviour {
[SerializeField] GameObject objectPrefab;//生成するオブジェクト
private ARRaycastManager raycastManager;
private List<ARRaycastHit> raycastHitList = new List<ARRaycastHit> ();
void Start () {
raycastManager = GetComponent<ARRaycastManager> ();
}
// Update is called once per frame
void Update () {
if (Input.touchCount > 0) {
Touch touch = Input.GetTouch (0);
if (touch.phase != TouchPhase.Ended) {
return;
}
if (raycastManager.Raycast (touch.position, raycastHitList, TrackableType.All)) {
Debug.Log ("Raycast成功");
Instantiate (objectPrefab, raycastHitList[0].pose.position, raycastHitList[0].pose.rotation);
} else {
Debug.Log ("Raycast失敗");
}
}
}
}
画面に触れて、指を話したタイミングでその指の位置の先に平面があるかをRaycast関数で調べ、trueだった場合はその場所を取得しInstantiateしてオブジェクトを生成します。
このコードを先ほどのAR Session Originに追加します。

Object Prefabには生成したいPrefabを用意して指定しましょう。
今回も前回と同様Sphereを作ってます。

実機にビルドして確認してみましょう!
平面を認識している状態で…

タップするとオブジェクトが生成されます!

特に個数の制限してないので何個でも出せます。

これだけ簡単に作れちゃうのはすごい!AR Foundation優秀ですね…。
まとめ
ARFoundationを触ってみました。いかがでしたでしょうか。
機能的にはARKit、ARCoreと同程度でこれだけ簡単にARアプリを、しかも両プラットフォームで作れちゃうのはかなり使い勝手が良いですね!
まだPreview段階ということもあり、動作が不安定だったり情報が少なかったりするのですがUnityはARFoundationに今後も力を入れていくでしょうし、ゲームエンジンで使うARとしては今後はARFoundationが主流になるのかな?と思いました。
興味のある方はぜひ試してみてください!