はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

ARFoundationで平面検知できたのでオブジェクトを落としてみよう

前回:
hatsune.hatenablog.jp


前回は、ARFoundationを使って平面検知をするアプリを作ってみました。
この平面検知ですが、検知した結果を表示するだけではなく、RigidBody(物理機能)をつけたオブジェクトを落とせば、検知した平面と干渉して、現実の床の上でオブジェクトがとまってくれたり、ころころと床を転がったりすることができます。

それでは、前回作成した平面検知のサンプルでオブジェクトを落としてみましょう。

初期表示で1m先に立方体があるので、この立方体をタップしたらRigidBody付きの立方体が生まれて自由落下(RigidBody付きなので)して平面検知した床=実物の床の上にどんどん積みあがっていくようなものをつくります。

立方体をタップする

ARFoundationで表示しているオブジェクトをタップしたかどうかを検出するためには、タップ位置を「Ray」として取得して、そのRayの線上にあるオブジェクトが何か?という判定が必要となります。

AR Raycast Managerの追加

「AR Session Origin」に「AR Raycast Mangaer」コンポーネントを追加します。

これでタップ位置を「Ray」として取得できます。

Rayの線上のオブジェクトを判定するスクリプトを作成

[Project]に「Script」フォルダを作成して、その中に「AirTapGesture」という名前でスクリプトを作成します。
gist.github.com

Rayを取得

var ray = this.ArCamera.ScreenPointToRay(touch.position);

ARFoundationのカメラオブジェクトがArCameraに割り当てられていれば、「ScreenPointToRay(touch.positoin)」にて、タップした位置がRayとして取得できます。

Rayが当たっているオブジェクトを取得

RaycastHit hit;
var hasHit = Physics.Raycast(ray, out hit);

「Physics.Raycast」を使ってRay上にあるコライダー(オブジェクトの物理情報)の情報を取得します。
そして、RayがぶつかっているコライダーのgameObjectを取得すれば、どんなオブジェクトにRayが当たっているかが分かります。

var target = hit.collider.gameObject;

該当オブジェクトを複製して自由落下

if (target.name.Contains("Cube"))
{
var clone = Instantiate(target); // Clone
clone.AddComponent();
}

該当オブジェクトが「Cube」であった場合だけ、「Instantiate」でそのCube自身を複製して、そこの「RigidBody」を追加して自由落下および物理演算が働くようにします。

スクリプトを「AR Session Origin」に割り当て

スクリプトが作成出来たら、Assets>Scriptの「AirTapGesture」を[Hierarchy]の「AR Session Origin」にドラッグアンドドロップします。

Rayを飛ばすカメラオブジェクトの割り当て

スプリプ途中で使うカメラとして、「AR Session Origin」の子オブジェクトのカメラを指定します。

実機デバッグ

実機準備

Android実機側では、まずは「開発者モード(Developer mode)」に変更して、さらに「USBデバッグ」ができるようにしておきます。

実機接続

Android実機側の準備ができたらUSBにて接続します。
準備がうまくできていると、ここで「USBデバッグを開始する」のようなダイアログが表示されるので、かならず「OK」をクリックします。

Unity側設定

[Run Device]には接続した実機を選択します。
[Development Build]と[Script Debugging]にもチェックをいれておきます。

実機実行

[Build And Run]をクリックして、ビルドと実機転送、そして実行を行います。
youtu.be