本日は MRTK の小ネタ枠です。
MRTKの空間認識メッシュを使ってオブジェクトの地面からの高さを計算する方法を記事にします。
MRTKの空間認識
MRTK の空間認識システムではアプリケーション内で現実世界のジオメトリを表すメッシュのコレクションが提供されます
docs.microsoft.com
MRTK の基本設定を行ったプロジェクトでは以下の通り、空間認識メッシュのレイヤー番号を取得できます。
// 空間認識のオブザーバを取得する IMixedRealitySpatialAwarenessMeshObserver SpatialAwarenessMeshObserver = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>(); // オブザーバからレイヤー番号を取得する int spatialAwarenessLayer = SpatialAwarenessMeshObserver.MeshPhysicsLayer;
MRTK のインポートとサンプルシーンの作成MRTKの基本設定
MRTK のインポートと HoloLens 向けプロジェクトの基本設定の手順は以下の記事を参照してください。
bluebirdofoz.hatenablog.com
また MRTK の MeshObservers を利用すると Unity エディター上で仮想メッシュを表示して動作確認を行うことができます。
bluebirdofoz.hatenablog.com
今回はこれらの設定を既に行っているホロモンアプリのプロジェクト上で試します。
サンプルコード
アタッチされたオブジェクトから真下の空間認識レイヤーに Raycast を飛ばして高さを求めるサンプルコードを作成しました。
・HeadHeightChecker.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; // CoreSystemへのアクセスのため using Microsoft.MixedReality.Toolkit; // 空間認識情報の取得のため using Microsoft.MixedReality.Toolkit.SpatialAwareness; namespace HoloMonApp.Player { public class HeadHeightChecker : MonoBehaviour { [SerializeField, Tooltip("高さの上限値(m)")] private float p_HeightMax = 2.0f; [SerializeField, Tooltip("空間認識レイヤー(ヒット判定レイヤー)")] int p_SpatialAwarenessLayer; [SerializeField, Tooltip("現在の高さ(m)")] private float p_CurrentHeight; /// <summary> /// 現在の高さ(m) /// </summary> public float CurrentHeight => p_CurrentHeight; // Start is called before the first frame update void Start() { // 空間認識のオブザーバを取得する IMixedRealitySpatialAwarenessMeshObserver SpatialAwarenessMeshObserver = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>(); // オブザーバからレイヤー番号を取得する p_SpatialAwarenessLayer = SpatialAwarenessMeshObserver.MeshPhysicsLayer; } // Update is called once per frame void Update() { // レイキャストをプレイヤーの位置から真下に落とす Vector3 playerPosition = this.gameObject.transform.position; Ray ray = new Ray(playerPosition, -Vector3.up); // 空間認識レイヤー用マスク int layerMask = 1 << p_SpatialAwarenessLayer; // レイキャストのヒット情報を取得する if (Physics.Raycast(ray, out RaycastHit hitInfo, Mathf.Infinity, layerMask)) { // ヒット位置(高さ)が上限値を超えていなければ高さとして代入する p_CurrentHeight = (hitInfo.distance < p_HeightMax) ? hitInfo.distance : p_HeightMax; } } } }
レイキャストのレイヤーマスクを設定して空間認識レイヤーにのみ、レイキャストがヒットするようにしています。
docs.unity3d.com
今回はこのスクリプトをプレイヤーの頭部追従オブジェくトに設定して、プレイヤーの頭の高さを計測してみます。
動作確認
シーンを再生して動作を確認します。
CurrentHeight の変数を参照すると、空間認識メッシュからの現在の高さが取得できます。