MRが楽しい

MRやVRについて学習したことを書き残す

MRTKを使ってHoloLensを被っている人の足元の位置を追跡する

本日は MRTK の小ネタ枠です。
MRTKを使ってHoloLensを被っている人の足元の位置を追跡する方法を記事にします。
f:id:bluebirdofoz:20210215005640j:plain

サンプルプロジェクトの作成

以下の記事に従って MRTK をインポートしたサンプルプロジェクトを作成します。
bluebirdofoz.hatenablog.com

更にエディター上でデバッグするため、以下の手順でエディター実行時に仮想メッシュが表示されるようにしておきます。
bluebirdofoz.hatenablog.com
f:id:bluebirdofoz:20210215005703j:plain

足元の追跡を行うスクリプト

最初に足元の位置に追従させる Sphere オブジェクトを作成します。
追跡にはレイキャストのヒット判定を利用するので、Collider を無効化して誤認識が発生しないようにしておきます。
f:id:bluebirdofoz:20210215005713j:plain

足元を追跡するスクリプトを作成します。
メインカメラから真下にレイを飛ばし、有意なヒット位置が取得できればオブジェクトを移動します。
・FootPositionTracking.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FootPositionTracking : MonoBehaviour
{
    [SerializeField, Tooltip("高さのオフセット")]
    private float p_YAxisOffset = 0.1f;

    [SerializeField, Tooltip("足元までの上限距離")]
    private float p_HeightMax = 2.0f;

    /// <summary>
    /// 開始処理
    /// </summary>
    void Start()
    {
        
    }

    /// <summary>
    /// 定期処理
    /// </summary>
    void LateUpdate()
    {
        // 追跡の正否
        bool isTracking = false;

        // レイキャストをメインカメラから真下に落とす
        Ray ray = new Ray(Camera.main.transform.position, -Vector3.up);
        RaycastHit hitInfo = new RaycastHit();
        // レイキャストのヒット情報を取得する
        if (Physics.Raycast(ray, out hitInfo))
        {
            // ヒット位置が足元までの上限距離を超えているかチェックする
            if (hitInfo.distance < p_HeightMax)
            {
                // 超えていなければヒット位置を足元として自身の位置を移動する
                this.transform.position = new Vector3(
                    hitInfo.point.x,
                    hitInfo.point.y + p_YAxisOffset,
                    hitInfo.point.z);
                // 追跡の成功
                isTracking = true;
            }
        }
        if (isTracking == false)
        {
            // 追跡に失敗した場合はカメラ真下の上限距離の位置に自身の位置を移動する
            this.transform.position = new Vector3(
                Camera.main.transform.position.x,
                Camera.main.transform.position.y - p_HeightMax,
                Camera.main.transform.position.z);
        }
    }
}

f:id:bluebirdofoz:20210215005724j:plain

作成したスクリプトを先ほどの Sphere オブジェクトにアタッチします。
f:id:bluebirdofoz:20210215005733j:plain

これで設定完了です。

動作確認

エディター上でシーンを再生して確認してみます。
カメラ真下の地面の位置に Sphere オブジェクトが常に追従すれば成功です。
f:id:bluebirdofoz:20210215005744j:plain