MRが楽しい

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

HoloLens2でホロモンアプリを作る その16(ホロモンを見ると恥ずかしがって踊るのを止める)

本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
f:id:bluebirdofoz:20210313232954j:plain

ホロモンを見ると恥ずかしがって踊るのを止める機能を追加するメモです。

MRTKで視線入力を利用する

視線入力の機能を有効化し、更にエディター上での視線入力の試験を有効にします。
詳細な手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com

以下の4つの設定を行うことで視線入力が可能になります。

WindowsMixedRealityEyeGazeDataProviderの設定

[MixedRealityToolkit]オブジェクトの[Inspector]ビューを開き、視線入力のデータプロバイダーを設定します。
[Input]タブの[Input Data Provider]欄にプロバイダーを追加します。
f:id:bluebirdofoz:20210313233014j:plain

EyeGazeProviderの設定

[Input]タブの[Pointer]欄を開き、[Gaze Settings]に[EyeGazeProvider]を設定します。
[Is Eye Tracking Enabled]にチェックを入れると、視線入力に追従するポインターを設定できます。
f:id:bluebirdofoz:20210313233027j:plain

GazeInputのCapabilities追加

[Project Settings]を開き、[Player]タブの[Publishing Settings -> Capabilities]を開きます。
[GazeInput]の Capabilities にチェックを入れて、視線入力の機能を有効化します。
f:id:bluebirdofoz:20210313233039j:plain

EyeGazeSimulationの有効化

[Input]タブの[Input Data Provider]欄にある[Input Simulation Service]のプロバイダーを開きます。
[Eye Gaze Simulation]の設定を[Camera Forward Axis]に設定することで、エディター上での視線入力の動作確認が行えるようになります。
f:id:bluebirdofoz:20210313233056j:plain

視線入力コンポーネントの追加

シーンに視線入力のイベントを作成します。
オブジェクトにアタリ判定の Collider と EveTrackingTarget スクリプトを設定します。
見たときにイベントが発生する[On Look At Start()]と、見るのを止めたときにイベントが発生する[On Look Away()]にイベントを設定しました。
f:id:bluebirdofoz:20210313233107j:plain

今回は以下のように視線入力のイベント変化を UniRx の ReactiveProperty でキャッチできるようにしてみました。
・HoloMonEyeGazeFeelSingleton.cs

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

namespace HMProject.HoloMon
{
    public class HoloMonEyeGazeFeelSingleton : MonoBehaviour
    {
        /// <summary>
        /// 単一インスタンス
        /// </summary>
        private static HoloMonEyeGazeFeelSingleton ps_instance;

        /// <summary>
        /// 参照用インスタンス
        /// </summary>
        public static HoloMonEyeGazeFeelSingleton Instance
        {
            get
            {
                if (ps_instance == null && ps_searchForInstance)
                {
                    ps_searchForInstance = false;
                    var ps_instances = FindObjectsOfType<HoloMonEyeGazeFeelSingleton>();
                    if (ps_instances.Length == 1)
                    {
                        ps_instance = ps_instances[0];
                    }
                    else if (ps_instances.Length > 1)
                    {
                        Debug.LogErrorFormat("Expected exactly 1 {0} but found {1}.", ps_instance.GetType().ToString(), ps_instances.Length);
                    }
                }
                return ps_instance;
            }
        }

        private static bool ps_searchForInstance = true;


        /// <summary>
        /// ホロモンに向けられた視線の状態
        /// </summary>
        [SerializeField, Tooltip("ホロモンに向けられた視線の状態")]
        private BoolReactiveProperty p_HoloMonEyeGazeFeel = new BoolReactiveProperty(false);

        /// <summary>
        /// ホロモンに向けられた視線の状態のReadOnlyReactivePropertyの保持変数
        /// </summary>
        private IReadOnlyReactiveProperty<bool> p_IReadOnlyReactivePropertyHoloMonListenWord;

        /// <summary>
        /// ホロモンに向けられた視線の状態のReadOnlyReactivePropertyの参照変数
        /// </summary>
        public IReadOnlyReactiveProperty<bool> IReadOnlyReactivePropertyHoloMonListenWord
            => p_IReadOnlyReactivePropertyHoloMonListenWord
            ?? (p_IReadOnlyReactivePropertyHoloMonListenWord = p_HoloMonEyeGazeFeel.ToSequentialReadOnlyReactiveProperty());



        /// <summary>
        /// 視線の変化
        /// </summary>
        /// <param name="a_IsSeen"></param>
        private void ReceptionEyeGazeFeel(bool a_IsSeen)
        {
            // 変数の登録を行う
            // SetValueAndForceNotify で強制的に通知を飛ばす
            p_HoloMonEyeGazeFeel.SetValueAndForceNotify(a_IsSeen);
        }



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

        /// <summary>
        /// 定期処理
        /// </summary>
        void Update()
        {
        }

        /// <summary>
        /// ホロモンが視線を受けたかどうか
        /// </summary>
        /// <param name="a_IsSeen"></param>
        public void EyeGazeFeelHoloMon(bool a_IsSeen)
        {
            ReceptionEyeGazeFeel(a_IsSeen);
        }
    }
}

f:id:bluebirdofoz:20210313233123j:plain

動作確認

視線入力の変化に合わせてアニメーションを切り替える実装を追加し、動作確認を行いました。
「踊って」というとホロモンが踊り出します。
f:id:bluebirdofoz:20210313233133j:plain

このときにホロモンを見ると、ホロモンが恥ずかしがって踊るのを止めてしまいます。
f:id:bluebirdofoz:20210313233144j:plain