MRが楽しい

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

MRTKを使って視線の位置に常にポインターを表示する

本日は MRTK の小ネタ枠です。
MRTKを使って視線の位置に常にポインターを表示する方法を記事にします。
f:id:bluebirdofoz:20210518001259j:plain

MRTKでの視線ポインターの有効化

MRTK のシーンで視線によるポインターを有効化する手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com
f:id:bluebirdofoz:20210518001315j:plain

通常の視線ポインターの動作

上記の記事で設定する視線ポインターは常時表示されるわけではなく、ハンドジョイントなどを表示すると消えてしまします。
これは視線ポインターはあくまでポインターの1つであるため、ハンドレイなどの他のポインターの優先度が高くなることがあるためです
f:id:bluebirdofoz:20210518001340j:plain

視線の位置に常にポインターを表示する

視線の位置に常にポインターを表示するには MRTK の CoreSystem から直接視線の情報を取得します。
指定のプレハブを視線のヒット位置、または、直線状の一定距離に表示する以下のスクリプトを作成しました。
・EyeGazeTracking.cs

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

using Microsoft.MixedReality.Toolkit;
using Microsoft.MixedReality.Toolkit.Input;

public class EyeGazeTracking : MonoBehaviour
{
    /// <summary>
    /// ポインターオブジェクト
    /// </summary>
    [SerializeField, Tooltip("ポインタープレハブ")]
    private GameObject m_SpawnPrefab;

    /// <summary>
    /// スポーンオブジェクトの参照
    /// </summary>
    private GameObject m_Pointer;

    /// <summary>
    /// 視線データの参照
    /// </summary>
    private IMixedRealityEyeGazeProvider m_EyeGazeProvider;

    /// <summary>
    /// 開始処理
    /// </summary>
    private void Start()
    {
        // 視線データの参照を取得
        m_EyeGazeProvider = CoreServices.InputSystem.EyeGazeProvider;
    }

    /// <summary>
    /// 定期実行
    /// </summary>
    private void Update()
    {
        // 視線トラッキングが有効か否か
        if(m_EyeGazeProvider.IsEyeTrackingEnabled)
        {
            // 視線のヒット位置にポインターを移動する
            m_Pointer.transform.position = m_EyeGazeProvider.HitPosition;

            // ヒット位置が存在しない(距離 0.0f)の場合
            if(m_EyeGazeProvider.HitInfo.distance <= 0.0f)
            {
                // 視線方向 2.0 メートル先の位置にポインターを表示
                float defaultDistanceInMeters = 2.0f;
                m_Pointer.transform.position =
                    m_EyeGazeProvider.GazeOrigin +
                    m_EyeGazeProvider.GazeDirection.normalized * defaultDistanceInMeters;
            }
        }
    }

    /// <summary>
    /// アクティブ時の処理
    /// </summary>
    private void OnEnable()
    {
        // プレハブを生成する
        m_Pointer = Instantiate(m_SpawnPrefab);
    }

    /// <summary>
    /// 非アクティブ時の処理
    /// </summary>
    private void OnDisable()
    {
        // プレハブを破棄する
        Destroy(m_Pointer);
    }
}

f:id:bluebirdofoz:20210518001355j:plain

適当なゲームオブジェクトにスクリプトを追加し、ポインターとして表示するプレハブを指定します。
f:id:bluebirdofoz:20210518001420j:plain

動作確認

シーンを再生して動作確認を行います。
ハンドレイを表示しても視線のポインターが表示されています。
f:id:bluebirdofoz:20210518001433j:plain

これはポインターの優先度が変わっても CoreSystem から視線データの情報が取得できるためです。