本日はHoloLensの表現の調査枠です。
HoloLensではアプリケーションの起動位置がUnityの原点になります。
OculusQuestなどのVRでは使用する際のキャリブレーションで取得した床の高さが原点になるので、ユーザーの身長を考慮する必要があまりありませんが、HoloLensの場合いくつかの問題が発生する場合があります。
例えば、プレイヤーの足元にオブジェクトを配置したい、床にオブジェクトを配置したいという場合、VRデバイス向け開発ではUnityの原点のY=0の座標に合わせて配置しますが、HoloLensの場合は一度SpatialAwarenessで生成されたメッシュから床を取得して配置するという作業が必要です。
ツールとしてはSceneUnderStandingを使用するところですが、現実空間の環境に大きく制約を受けます。
そこでオリジナルで床を検出しオブジェクトを配置する機能を作成しました、
〇実機
〇FroorGeter
今回作成したツールでは次のような機能をサポートしています。
・現実空間に合わせ床を検知して床の高さを記録する
・SpatialMeshを削除して床に合わせてPlaneを貼る
・床の高さ基準でオブジェクトの配置
・MRTKv2で完結する(外部プロジェクトを必要としません。)
〇ソースコード
〇使い方・仕組み
アプリが起動するとSpatialAwarenesによってSpatialMeshが作成されます。
十分にメッシュが作成されるのを待って(7秒)TaoToPlaceをアタッチしたCubeが現れます。
//初回のsecは7,floorGeter=TapToPlaceのアタッチされている。Cubeの親オブジェクト IEnumerator FloorSetting(float sec) { TapToPlace ttp = floorGeter.transform.Find("Cube").gameObject.GetComponent<TapToPlace>(); yield return new WaitForSeconds(sec); floorGeter.SetActive(true); yield return new WaitForSeconds(2); ttp.enabled = false; }
TapToPlaceはSpatialMesh上にオブジェクトを配置することができるMRTKのコンポーネントです。
2秒の間ユーザーの頭の向きに合わせてCubeがSpatialMesh上を動きます。
その後TapToPlaceがディアクティブに変わり移動が止まります。この時床の上にCubeが配置されている場合"Yes"、違う場合"No"とユーザーに発音させます。
yield return new WaitForSeconds(2); ttp.enabled = false;
Yesの場合Cebeが削除され、CubeのY軸座標が床の高さになります。(-1くらい)この情報が[StageSettings]コンポーネントの[Floor]に渡されます。
また、[Floor]の高さにUnityのプリミティブ3DPlaneを生成し、レンダラーをディアクティブにすることでコライダーを貼ります。
最後に[StageObject]に指定していたオブジェクトが表示されます。
[StageObject]の子オブジェクトに床の高さ基準に配置したいオブジェクトと、床からの高さをY軸基準で配置することでHoloLensアプリ上で現実の床の高さ基準の配置を行います。
Noの場合は再度オブジェクトの移動が行われます。
〇メリット・デメリット
メリット
・SceneUnderStandingなどを使用せず、どこでも、どのような現実環境でも使用できる。
・ユーザーの身長を推測できる。
・床のまっ平なSpatialMeshが貼れる。
・床をユーザーに選ばせるので正確に床の高さを検知できる。
デメリット
・アプリ起動時のユーザー体験に一工程かかってしまう。
・ユーザーのボイスを使用する(万人に対応できない可能性がある。)
〇まとめ
床基準にオブジェクトを配置することでユーザーの身長や周囲の様々な環境に依存しないアプリケーションが作れそうです!