見出し画像

ARFoundationをさわってみた

今回は、 Unity 向けに ARKit と ARCore の機能をまとめた  AR Foundation について調べました。

開発環境
・Unity 2019.1.1f1 (2019.1以降が推奨されています)
・AR Foundation 2.1.0
・ARCore XR Plugin 2.1.0
・ARKit XR Plugin 2.1.0

環境構築1.必要なパッケージをインストール

画像1

Unity2019.1では ARFoundation は preview となっているので、まず、Package Manager > Advanced で Show preview packages を選択して、一覧に表示します。

一覧の中から AR Foundation 、 ARCore XR Plugin 、 ARKit XR Plugin の3つをインストールしましょう。

環境構築2.Android の API レベルを変更

画像2

Project Settings > Player > Identification > Minimum API Level を 7.0以上に変更します。

環境構築3.Hierarchy に必要な GameObject を配置

はじめから置かれている Main Camera を削除します。

画像3

GameObject > XR > AR Session Origin と AR Session をヒエラルキーに配置します。

これで ARFoundation の開発環境が整いました😎

動かしてみる

ここからはサンプルプロジェクトのシーンを動かしながら、各機能を確認していきます。

動かしてみる1.平面を検出する

画像4

GameObject > XR > AR Default Plane を一旦ヒエラルキーに配置して、 Prefab 化します。Prefab 化したら、ヒエラルキーから削除しましょう。

画像5

AR Session Origin に AR Plane Managerコンポーネントを追加します。
次に、AR Plane Manager コンポーネントの Plane Plefab に Prefab 化した AR Default Plane を設定します。

この作業で、 Android ・ iOS 両方に対応した平面検出が実装できました。

実機にビルドして動かすとこんな感じです。
ここまで、コードを一切書かずに作ることができます。

・検出速度、精度共に ARKit 、 ARCore と同じくらいの性能です。
・iOS 上で動かす時のみ ARKit 同様、検出した平面が存在しない方向を向いた後に平面に向き直ると、平面の場所が大きくズレてしまう事があります。

動かしてみる2.平面にオブジェクトを置く

画像6

平面に向けて Ray を飛ばすために、 AR Session Origin に AR Raycast Managerコンポーネントを追加します。

var hits = new List<ARRaycastHit>();
if (_arRaycastManager.Raycast(touch.position, hits,TrackableType.PlaneWithinPolygon))
{
   Pose pose = hits[0].pose;
   // ここに生成、移動処理を書く
}

AR Raycast Managerコンポーネントの ARRaycastManager.Raycastメソッド で、平面に向けて Ray を飛ばして、 List<ARRaycastHit> を取得することができます。
ARRaycastHit から Pose を取得してオブジェクトを生成、移動させましょう。

出来上がったものがこちらです。

動かしてみる3.マーカー認識

画像7

AR Session Origin に AR Tracked Image Managerコンポーネント を追加します。

画像8

Project ビューで右クリック -> Create -> XR -> Reference Image Library を作成します。

画像9

Add Image ボタンをクリックして、項目を増やし、Reference Image Library に認識したいマーカー画像を設定する。
※ Specify Size を有効にし、 Physical Size(物理サイズ)を設定すると、認識の精度が上がります。

画像10

1.AR Tracked Image Managerコンポーネント に作成した Reference Image Library を設定する
検出したマーカーの位置に3D モデル等を表示したい場合は、 Tracked Image Prefab に任意の Prefab を設定してください。

1.ARTrackedImageManager.trackedImagesChanged に Event を登録する事で、 ARTrackedImagesChangedEventArgsクラス が取得できる
2.ARTrackedImagesChangedEventArgsクラス には、「新たに検出したマーカー」、「情報が更新されたマーカー」、「検出されなくなったマーカー」の情報 (ARTrackedImageクラス) が added 、 updated 、 removed にそれぞれ格納されている
ARTrackedImage クラス から取得した値をもとに3D モデル等の Scale を調整します。

Position 、 Rotation は AR Session Originコンポーネント が検出したマーカーに合わせて自動で調整しているようです。

移動するマーカーには対応していませんでした。
マーカーの移動後の再認識までの速度は iOS の方が早いようです。

動かしてみる4.顔認識

画像11

AR Session Origin に AR Face Managerコンポーネント を追加します。
AR Face Managerコンポーネント の Face Prefab に、顔に重ねて表示する Prefab を設定します。

・iOS 、 Android どちらも同じプロジェクトでビルド出来ますが、 Rig は ARKit と同様のものを取得しているので、 Android では顔の位置と向きのみのトラッキングとなり、 Rig は動きません。
・UnityEngine.XR.ARCore.ARCoreFaceSubsystem.GetRegionPose s関数 で、 ARKit の Rig を ARCore の Rig に変換する事が可能です。(変換可能なのは ARCore に定義されている額2点と鼻1点の合計3点のみ)

動かしてみる5.Environment Probes

画像12

AR Session Origin に AR Environment Probe Managerコンポーネント を追加します。

画像13

周囲の風景を写したい GameObject のマテリアルの Metallic 、 Smoothness を1に設定します。(この2つの値で見た目の調整ができます。)
ちなみに、iOS のみ対応です。

画像14

カメラに映った物を映し出すので、本来映らないものまで映り込んでしまうことに注意です。(赤枠で囲んだ部分に本来写らないはずのコップやキーボードが写っていることが確認できます。)
ARKit の同機能とほぼ同じです。

動かしてみる6.World Map

ARKit 、 ARCore 共に似たような機能はあるが AR Foundation では iOS のみ対応しています。

ARKitSessionSubsystem sessionSubsystem = (ARKitSessionSubsystem)m_ARSession.subsystem;
ARWorldMapRequest request = sessionSubsystem.GetARWorldMapAsync();
// World Map を取得
ARWorldMap worldMap = request.GetWorldMap();
// シリアライズ化
var data = worldMap.Serialize(Allocator.Temp);

UnityEngine.XR.ARKit.ARKitSessionSubsystem から WorldMap を取得し、シリアライズ化する事で、 AR 空間の情報を保存する事ができます。

// デシリアライズ
if (ARWorldMap.TryDeserialize(data, out worldMap))
{
   data.Dispose();
}
// World Map を適用
sessionSubsystem.ApplyWorldMap(worldMap);

byte 配列で保存してある World Map をデシリアライズする事で、同じ AR 空間を再現する事ができます。

検出した平面や、生成した GameObject の位置、向き、大きさを再現する事ができています。
ロード用のメソッドを呼んでから、再現されるまで、3秒程かかります。

まとめ

Unity Technologies が作っているだけあって、 UnityEditor 上で簡単に AR が実装できました。
ただ、 ARFoundation を使用して iOS 向けに作ったプロジェクトを、そのまま Android 向けにビルドすると動作に差が生まれることがありそうです。
動作検証の際にはご注意を!

この記事が気に入ったらサポートをしてみませんか?