Unity MRTK Hololens2眼动交互

csharp 复制代码
/*
 * ==================================================================================================================
 *
 * 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)
        {
        }
    }
}
csharp 复制代码
/*
 * ==================================================================================================================
 *
 * 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()
        {
        }
    }
}
csharp 复制代码
/*
 * ==================================================================================================================
 *
 * 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组件挂载到新建的物体上就可以了

相关推荐
AllBlue1 小时前
unity导出成安卓工程,集成到安卓显示
android·unity·游戏引擎
梓贤Vigo2 小时前
【Axure原型分享】AI图片变清晰
ai·交互·产品经理·axure·原型
Sator14 小时前
Unity的FishNet相关知识
网络·unity·游戏引擎
AllBlue4 小时前
安卓调用unity中的方法
android·unity·游戏引擎
李岱诚5 小时前
epic商城下载,ue4报错处理
游戏引擎·ue4
jtymyxmz20 小时前
《Unity Shader》10.1.4 折射
unity·游戏引擎
在路上看风景20 小时前
12. Burst
unity
平行云PVT1 天前
实时云渲染解决UE5 像素流插件迁移及传输数据受限问题
unity·ue5·xr·实时云渲染·云桌面·像素流·云推流
熬夜敲代码的小N1 天前
Unity WebRequest高级操作:构建高效稳定的网络通信模块
android·数据结构·unity·游戏引擎
萘柰奈1 天前
Unity【小问题】----URP项目中加载AssetBundle中的预设体即使加载了依赖的材质依然是紫色的问题
unity·游戏引擎·材质