Unity MRTK Hololens2眼动交互

/*
 * ==================================================================================================================
 *
 * UnityVersion : 2021.3.6f1
 * Description : 眼部交互基类
 * Author: 
 * CreateTime : 2023-10-11  09:43:20
 * Version : V1.0.0
 * 
 * ==================================================================================================================
 */

using System.Collections.Generic;
using Microsoft.MixedReality.Toolkit.Input;
using UnityEngine;

namespace MRTKExtend.EyeTracking
{
    
    
    [RequireComponent(typeof(Collider))]
    public abstract class BaseFocus : MonoBehaviour, IMixedRealityFocusHandler, IMixedRealityFocusChangedHandler
    {
    
    
        [SerializeField] [Tooltip("是否启用焦点?")] private bool focusEnabled = true;

        /// <summary>
        /// 是否为启用了焦点
        /// </summary>
        public virtual bool FocusEnabled
        {
    
    
            get => focusEnabled;
            set => focusEnabled = value;
        }

        /// <summary>
        /// 此对象当前是否有焦点
        /// </summary>
        public virtual bool HasFocus => FocusEnabled && Focusers.Count > 0;

        /// <summary>
        /// 当前聚焦此对象的列表
        /// </summary>
        public List<IMixedRealityPointer> Focusers {
    
     get; } = new(0);

        /// <summary>
        /// 焦点进入
        /// </summary>
        public virtual void OnFocusEnter(FocusEventData eventData)
        {
    
    
        }

        /// <summary>
        /// 焦点退出
        /// </summary>
        public virtual void OnFocusExit(FocusEventData eventData)
        {
    
    
        }

        public virtual void OnBeforeFocusChange(FocusEventData eventData)
        {
    
    
            //如果是新的目标对象,将指针添加到焦点列表。
            if (eventData.NewFocusedObject == gameObject)
            {
    
    
                eventData.Pointer.FocusTarget = this;
                Focusers.Add(eventData.Pointer);
            }
            //如果是旧的聚焦目标对象,从列表中删除指针。

            else if (eventData.OldFocusedObject == gameObject)
            {
    
    
                Focusers.Remove(eventData.Pointer);

                //如果没有新的焦点目标,从指针中清除焦点目标。

                if (eventData.NewFocusedObject == null)
                {
    
    
                    eventData.Pointer.FocusTarget = null;
                }
            }
        }

        public virtual void OnFocusChanged(FocusEventData eventData)
        {
    
    
        }
    }
}
/*
 * ==================================================================================================================
 *
 * UnityVersion : 2021.3.6f1
 * Description : 眼部交互
 * Author: 
 * CreateTime : 2023-10-11  09:21:40
 * Version : V1.0.0
 * 
 * ==================================================================================================================
 */

using System;
using Microsoft.MixedReality.Toolkit.Input;
using UnityEngine;

namespace MRTKExtend.EyeTracking
{
    
    
    public abstract class BaseEyeFocus : BaseFocus
    {
    
    
        [Tooltip("可配置的持续时间,用于在用户查注释目标的时间超过此持续时间时触发事件。")] [SerializeField] [Range(0, 20)]
        private float timeToTriggerDwellInSec = 5;

        /// <summary>
        /// 停留时间
        /// </summary>
        private DateTime _dwellTimer;

        /// <summary>
        /// 是否持续注视
        /// </summary>
        private bool _isDwelling = false;

        /// <summary>
        /// 是否注视
        /// </summary>
        private bool _hadFocus = false;

        /// <summary>
        /// 处理光标进入目标时的突出显示目标。
        /// </summary>
        protected virtual void Update()
        {
    
    
            if (!HasFocus && _hadFocus)
            {
    
    
                OnEyeFocusStop();
                _isDwelling = false;
                _hadFocus = false;
            }
            else if (HasFocus)
            {
    
    
                if (!_hadFocus)
                {
    
    
                    OnEyeFocusStart();
                    _dwellTimer = DateTime.UtcNow;
                    _hadFocus = true;
                }
                else
                {
    
    
                    OnEyeFocusStay();

                    if (!_isDwelling && (DateTime.UtcNow - _dwellTimer).TotalSeconds > timeToTriggerDwellInSec)
                    {
    
    
                        OnEyeFocusDwell();
                        _isDwelling = true;
                    }
                }
            }
        }

        /// <inheritdoc />
        public override void OnBeforeFocusChange(FocusEventData eventData)
        {
    
    
            //如果注视新的目标对象,将指针添加到焦点列表。
            if (eventData.NewFocusedObject == gameObject &&
                eventData.Pointer.InputSourceParent.SourceType == InputSourceType.Eyes)
            {
    
    
                eventData.Pointer.FocusTarget = this;
                Focusers.Add(eventData.Pointer);
            }
            //如果注视是旧的聚焦目标对象,从列表中删除指针。
            else if (eventData.OldFocusedObject == gameObject)
            {
    
    
                Focusers.Remove(eventData.Pointer);

                // 如果没有新目标,从指针中清除焦点目标
                if (eventData.NewFocusedObject == null)
                {
    
    
                    eventData.Pointer.FocusTarget = null;
                }
            }
        }

        /// <summary>
        ///一旦眼睛凝视射线开始与该目标的碰撞体接触,就会触发。
        /// </summary>
        protected virtual void OnEyeFocusStart()
        {
    
    
        }

        /// <summary>
        /// 在眼睛凝视射线与该目标的碰撞体持续接触时触发。
        /// </summary>
        protected virtual void OnEyeFocusStay()
        {
    
    
        }

        /// <summary>
        ///一旦眼睛凝视射线停止与该目标的碰撞体,就会触发。
        /// </summary>
        protected virtual void OnEyeFocusStop()
        {
    
    
        }

        /// <summary>
        /// 一旦眼睛凝视射线与该目标的碰撞体接触指定时间后触发。
        /// </summary>
        protected virtual void OnEyeFocusDwell()
        {
    
    
        }
    }
}
/*
 * ==================================================================================================================
 *
 * UnityVersion : 2021.3.6f1
 * Description : 功能描述
 * Author: 
 * CreateTime : 2023-10-10  16:09:27
 * Version : V1.0.0
 * 
 * ==================================================================================================================
 */

using MRTKExtend.EyeTracking;
using UnityEngine;

public class EyeTrackingTest : BaseEyeFocus
{
    
    
    protected override void OnEyeFocusStay()
    {
    
    
        Debug.Log("OnEyeFocusStay");
        //todo something
        RotateHitTarget();
    }

    protected override void OnEyeFocusStart()
    {
    
    
        Debug.Log("OnEyeFocusStart");
        //todo something

    }

    protected override void OnEyeFocusStop()
    {
    
    
        Debug.Log("OnEyeFocusStop");
        //todo something

    }

    protected override void OnEyeFocusDwell()
    {
    
    
        Debug.Log("OnEyeFocusDwell");
        //todo something

    }
    
    private void RotateHitTarget()
    {
    
    
        transform.localEulerAngles += new Vector3(0, 0.1f, 0);
    }
}

在场景中新建一个物体,将EyeTrackingTest组件挂载到新建的物体上就可以了
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42862278/article/details/133761760