ARKit3 & Unity でAR Foundationを使ってみたメモ

#はじめに

2020現在、ARkitをUnityと連携させてアプリを作る場合に気をつけておきたいのが、
Unity-ARKit-Pluginでつくるパターンの記事を多く見かけますが、ARKit3以降は、AR Foundationから利用する形に変更されたとのことで、これから作る人はAR foundationの記事を参考にする必要があるということ。
ちなみに AR Foundation自体は、Unity開発者が使用できるインターフェイスを提供するだけで、AR機能自体は実装していないため、iOSならARKit XR Plugin、AndroidならARCore XR Pluginが必要であることも気をつけておくポイントです。

![about AR Foundation](https://blogs.unity3d.com/wp-content/uploads/2018/12/image4-1.png)

さて、自分も含めて、ARを始めるには、一体どこから始めれば良いのか？と戸惑いますが、
まずはサンプルコードの実行が何よりもわかりやすいと思います。

#サンプルコード
https://github.com/Unity-Technologies/arfoundation-samples


他にもサンプルに含まれている事例として...

>平面検知	Plane Detection
>環境光推定	Light Estimate
>画像トラッキング	Image Tracking
>物体トラッキング	Object Tracking
>空間共有	World Map
>顔認識	Face Tracking
>モーションキャプチャ	Body Tracking
>オクルージョン	People Occlusion

というものが存在しているが、実機の環境が色々と厳しくiPhoneの場合は、
FaceTracking,BodyTracking,PeopleOcclusionなどを実行したい場合はiPhoneX以降が必要であるなどいくつかハードウェアの観点でも注意する必要があります。

>ARKitの利用 >= A9以降のプロセッサ
>Face Tracking = True Depthカメラ
>BodyTracking,People Occlusion >= A12以降のプロセッサ


さて、サンプル中の「SimpleAR」が最も基本となる雛形で、ポイントクラウドの視覚化と平面の検出のdemoです。
https://github.com/Unity-Technologies/arfoundation-samples/tree/master/Assets/Scenes/SimpleAR

「ARKitはどうやって自己位置推定と環境マッピングを行なっているのか」
https://qiita.com/k-boy/items/1de8e9ed1260834d02af

という記事がとても分かりやすかったのですが、SLAMやVIOという技術を使って、ARという技術を実現しているのですが、

>SLAM（Simultaneous Localization and Mapping）はカメラで撮影された映像から環境の3次元情報とカメラの位置姿勢を>同時に推定する技術です。

このSimpleARに含まれているサンプルは、まさにカメラ中の特徴点を捉えて、それらを平面として捉えることで、そこにオブジェクトを配置することなどAR的な制御を可能にします。

平面にオブジェクトを設置する場合どのようにするかというと、とても簡単で、Raycastを用います。

元々Unityのゲームを作る場合、特定のオブジェクトから光線(Ray)を出し光線がぶつかった別のオブジェクトの座標を取得するRaycastという仕組みがあります。
ARの場合も、これと全く同じ仕組みで、カメラに移った特徴点から平面を検知->平面を検知した上でRayを飛ばして、物体を配置するという操作が可能になります。

ここに通常のゲームで用いるRaycastと、ARで用いるRaycastを記述してみますが、ほとんど同じように使うことができます。


```isnotar.c
//マウスポインタの位置からrayを飛ばして、どのオブジェクトが当たったかを判別する
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
{}
```

RaycastManagerを使って、平面状にRayを飛ばして、タッチした座標に何らかの物体を配置している例です。

```isar.c
m_RaycastManager = GetComponent<ARRaycastManager>();
if (rayManage.Raycast(Input.GetTouch(0).position, hitResults)) {
}
```

平面を検知している例。平面の他にも壁などの垂直面などの検知も可。
この写真のようにものがごちゃごちゃあると少し難しいが、何もない場所だとものが配置しやすい。
<img width="414" alt="Image from iOS (5).jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/086afa18-859e-303d-2ab0-422aa17beefd.jpeg">


さて、今回は、色々な事例の中から、ObjectTrackingのサンプルを試してみました。
Object Trackingは、これまでARなどで用いられていたQRコードのようなマーカーの代わりに物体をマーカーの代わりにすることができます。そのため、QRコードを不自然に貼るなどが必要ないことから、何らかの美術品の展示などにおける説明や、専門機器などの操作マニュアルなど将来的に色々なケースに利用できるのではないかと思います。

#Object Trackingを試してみる

##インストール

1.Unity 2019.2以降の最新を用意。
2.Unityを開き、「arfoundation-samples」リポジトリのルートにプロジェクトを読み込み
3.objectスキャナーをダウンロードして実行
https://developer.apple.com/documentation/arkit/scanning_and_detecting_3d_objects


##オブジェクトをスキャンする

###1.平らなところに置いて、オブジェクトをscanします。どうやら、大きさとしては、机における程度のものを想定しているようで、
それ以上や小さいものであると、エラーになってしまいます。実際の車などは現時点では難しいと思われます。。
![Image from iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/f31a5ca3-d852-ebb4-8172-295d0707c59f.jpeg)

###2.ボックスが出てくるため、指でスワイプして、なるべくオブジェクトと同じサイズに配置します。
![Image from iOS (3).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/310063b7-687e-c356-821f-ec09eb07dbee.jpeg)

###3.上下左右のボックスを埋めるようにスキャンすると、表示が100%になって、スキャンが終了します。
![Image from iOS (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/516d611a-2c52-789d-9ec7-b51fa0fd995e.jpeg)

###4.ReferenceObjectAssetsにスキャンしたデータを放り込む
<img width="701" alt="scan001.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/97dcc79e-73fb-4575-64b6-db47c66ab5b6.png">

###5.実行
![Image from iOS (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/feee1710-fc79-5f0f-1f7a-d413a5d65c85.jpeg)


#Conclusion

Object Trackingを試しみてましたが、スキャンするオブジェクトの大きさは机における程度のものである点だとか、またマーカーが反応するまでに少しタイムラグがあり、またマーカーを動かした場合も、スムーズにマーカーが付いて来ず、ある点をさかいにヒュっとマーカーが動くような感じになるので、少しストレスはありました。
今回はMonsterJamという車の玩具で試したのですが、このスキャンを元に、実物をARデバイスでみたときに、車の情報や過去の動画、ドライバー情報などがグラスに表示されたりすると、とても実用的だなと思いましたが、まだまだもう少し認識の精度が必要かなという印象を受けました。


#参考

https://gaprot.jp/2019/10/08/arfoundation/

https://qiita.com/sada_lp1/items/61dea96b102e8388f845

【ARKit】3Dオブジェクトをマーカーにする
http://nn-hokuson.hatenablog.com/entry/2019/06/25/192111

Unity ARKitのobject trackingにおける注意点
https://qiita.com/JunNishimura/items/54fa35fd2a72ef1a2827

arkit-3
https://blogs.unity3d.com/2019/06/06/ar-foundation-support-for-arkit-3/

https://blogs.unity3d.com/wp-content/uploads/2018/12/image4-1.png