ARKit2の新機能として追加されたARObjectAnchorをUnityで試してみます。
- ARObjectAnchorとは
- 開発環境
- ARReferenceObjectを作成する
- ARKitScannerを使ったARReferenceObjectの作成
- ARObjectAnchorを使う
- アプリで動かしてみる
- まとめ
ARObjectAnchorとは
現実の物体(オブジェクト)を検知して、Anchorの作成・トラッキングを行う機能です。
予め作成しておいたARReferenceObjectを元に検知を行います。
開発環境
ARKit2で追加された機能のため、iOS12およびXcode10が必要になります。
本記事執筆時点ではβ版のため、Apple Developerからダウンロードしました。
- ARKitに対応したデバイス(iPhone SEを使用)
- iOS12
- XCode10
- Unity 2018.1.5f1
Unity ARKit Pluginのインストール
Unity ARKit PluginはBitbucketのから"arkit2.0_beta"ブランチをダウンロードします。
https://bitbucket.org/Unity-Technologies/unity-arkit-plugin/downloads/?tab=branches
ダウンロード後、Assets以下のUnityARKitPluginをUnityプロジェクトのAssetsにフォルダごとコピーして使います。
ARKitを使うのに必要なUnityの設定については割愛します。"Camera usage description"を忘れなければ、なんとかなると思います。
ARReferenceObjectを作成する
検知したいオブジェクトをスキャンして、ARReferenceObjectを作成します。
ここが上手くできないと検知の精度が落ちるので、重要な作業です。
UnityARKitPluginにExamplesとして付属しているUnityObjectScannerをビルドすると、スキャン用のアプリが起動します。
UnityARKitPlugin > Examples > ARKit2.0 > UnityObjectScanner
BoundingBoxを対象オブジェクトに合わせる
アプリ起動後の手順として、まずはBoundingBoxでスキャン対象のオブジェクトを囲み、Axisをオブジェクトの中心に合わせます。
基本的な操作方法は、以下の通り。
BoundingBoxの移動:オブジェクト付近の平面をタップ
BoundingBoxの伸縮:BoundingBoxの面をタップしてドラッグ
BoundingBoxの平行移動:Axisをタップしてドラッグ
BoundingBoxの回転:画面を二本指タップした状態で回転
対象オブジェクトをスキャンする
BoundingBoxの位置を合わせたら、その状態で対象オブジェクトを複数の方向からスキャンします。"Create Objects"、"Detect Objects"のボタンを押す必要はありません。カメラをかざすことで、オブジェクト上のPointCloudが特徴点として検出されていきます。
ARReferenceObjectを保存する
スキャンが完了したら、アプリ上のUIでARReferenceObjectを作成・保存します。
"Create Objects"でBoundingBox内の特徴点からARReferenceObjectが作られ、リストに追加されます。 この処理は多少時間がかかることがあり、画面中央のウィンドウにファイル名のリスト(objScan_0,objScan_1,...)が表示されたら、作成完了した合図です。
最後に、"Save Objects"でARReferenceObjectをファイルとしてデバイスに保存します。これを忘れると、せっかくスキャンした結果を利用できなくなります。
他のボタンは以下の用途に使えます。スキャンだけを行う場合、必須ではないです。
"Detect Object"は検知モードのON/OFFです。スキャン結果を用いた検知のテストに使えます。
"Clear Objects"は"Create Objects"で作成したARReferenceObjectを全て削除します。
ARReferenceObjectをコピーする
iTunesのファイル共有からコピーするのが簡単です。
スキャンを行ったデバイスをMacに接続して、iTunesでファイル共有メニューを開きます。
アプリが作成したファイルに"ARReferenceObjects"という名称のフォルダがあり、ARReferenceObjectが保存されています。
フォルダごとMacにコピーしてFinderで開くと、拡張子が.arobjectのファイルがあるはずです。
このファイルをUnityにコピーして使います。
ARKitScannerを使ったARReferenceObjectの作成
スキャンを行う方法としてはもう一つ、Apple公式のサンプルコードをXcodeでビルドしたARKit Scannerが使えます。
スキャンの流れはUnityのサンプルと同じですが、BoundingBoxの作成、Scan、Test、ファイルの保存・共有とステップを踏んでいくUIとなっており、UnityObjectScannerよりもわかりやすいです。
スキャンの進捗に応じてパーセンテージが表示され、スキャンを行った面はBoundingBoxが着色される機能もあるため、全方向から満遍なくスキャンを行えます。
100%になっていなくても"Finish" > "Cancel"(Continueのキャンセル)でスキャンを終了できます。
最終的に作成されるのは.arobjectファイルなので、Unityでも使えます。
ファイルの転送にAirDropが使える点も便利です。
ARObjectAnchorを使う
作成したARReferenceObjectを使って、ARObjectAnchorの作成、コンテンツの重ね合わせを行います。
Unity ARKit PluginでARObjectAnchorを使うには、UnityARCameraManagerの"Detection Objects"にARReferenceObjectsSetAssetをセットします。
ARReferenceObjectsSetAssetは、プロジェクトウィンドウで右クリックから"Create" > "UnityARKitPlugin" > "ARReferenceObjectsSetAsset"で作成できます。
ARReferenceObjectsSetAssetには、検知対象のARReferenceObjectAssetを複数セットできます。
ARReferenceObjectAssetもプロジェクトウィンドウで右クリックから"Create" > "UnityARKitPlugin" > "ARReferenceObjectAsset"で作成できます。
ARReferenceObjectsAssetには、スキャンで作成した.arobjectファイルをARReferenceObjectとしてセットします。
ここまでで、ARSessionに検知対象のARReferenceObjectが設定され、ARObjectAnchorが作成されるようになります。
作成されたARObjectAnchorを使ってARコンテンツを重ねるにはスクリプトを使います。UnityARObjectAnchorで利用されているGenerateObjectAnchor.csが参考になります。
まず、Start()でARObjectAnchor作成時、更新時に実行するメソッドを定義します。
void Start () { UnityARSessionNativeInterface.ARObjectAnchorAddedEvent += AddObjectAnchor; UnityARSessionNativeInterface.ARObjectAnchorUpdatedEvent += UpdateObjectAnchor; }
ARSessionでオブジェクトが検知されると、定義したメソッドが呼ばれ、ARObjectAnchorが渡されます。
作成時に呼ばれるメソッド(AddObjectAnchor()
)では、ARObjectAnchorからposition、rotationを取得して、GameObjectを生成(Instantiate)しています。
void AddObjectAnchor(ARObjectAnchor arObjectAnchor) { Debug.Log ("object anchor added"); if (arObjectAnchor.referenceObjectName == referenceObjectAsset.objectName) { Vector3 position = UnityARMatrixOps.GetPosition (arObjectAnchor.transform); Quaternion rotation = UnityARMatrixOps.GetRotation (arObjectAnchor.transform); objectAnchorGO = Instantiate<GameObject> (prefabToGenerate, position, rotation); } }
検知したオブジェクトの位置が更新されると、更新されたARObjectAnchorが渡されます。
更新時のメソッド(UpdateObjectAnchor()
)では、生成したGameObjectの位置をARObjectAnchorの更新に合わせて上書きしています。
void UpdateObjectAnchor(ARObjectAnchor arObjectAnchor) { Debug.Log ("object anchor added"); if (arObjectAnchor.referenceObjectName == referenceObjectAsset.objectName) { objectAnchorGO.transform.position = UnityARMatrixOps.GetPosition (arObjectAnchor.transform); objectAnchorGO.transform.rotation = UnityARMatrixOps.GetRotation (arObjectAnchor.transform); } }
基本的には、上記のサンプルコードと同様にGameObjectの生成、位置の更新を行えばARコンテンツが現実のオブジェクトに重ねて表示され、対象が動いても追従するようになります。
複数のオブジェクトを検出しつつ、異なるARコンテンツを表示したい場合は、ARReferenceObjectAssetに設定したObjectNameがARObjectAnchorにセットされるため、何を検知したかを名称によって制御できます。
アプリで動かしてみる
まず、UnityARObjectAnchorと同様にAxisを表示してみます。
スキャンしたARReferenceObjectの精度にもよりますが、検知に数秒かかるようなこともなく、オブジェクトにカメラをかざすとすぐに検知してくれます。
よつぎドールの検知に成功した。 pic.twitter.com/bRvNm5oiD5
— jyuko (@jyuko49) 2018年8月1日
続いて、ARコンテンツを3D Textに変更して、追従のテストを行ってみました。
検知対象のオブジェクトが移動すると、テキストも移動していることがわかります。
いえーい。 pic.twitter.com/91kEioF3Ph
— jyuko (@jyuko49) 2018年8月1日
まとめ
ARKit2で追加されたARObjectAnchorは、現実の物体をARで拡張するのに適した機能です。
ARReferenceObjectのスキャンがやや面倒ではありますが、アプリの操作に慣れれば数分で作成できます。一度作成してしまえば、どのアプリでも使えますし、ファイルを共有することで同じ物を持っている人も使えます。
用途としてイメージしやすいのは、今回試したようにフィギュアや模型にエフェクトやUIを重ねる使い方でしょうか。市販されている製品であれば、ARReferenceObjectをインターネットで配布・共有できる点も魅力です。
また、物体の移動を検知できるので、チェスのような物の配置によって局面が変わるようなゲームにも使えそうです。
立体的な特徴が少なく検知が難しい場合、平面画像を検知・追従するARImageAnchorが代用できます。