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组件挂载到新建的物体上就可以了

相关推荐
zyh______11 小时前
unity值属性修改步骤
unity·游戏引擎
UXbot12 小时前
为什么 AI 正在重新定义 UI 设计工具的入门门槛
前端·人工智能·低代码·ui·交互·ai编程·ux
小贺儿开发13 小时前
Unity3D 四星探秘:手势互动演示
科技·unity·人机交互·科普·硬件·leap motion·互动
风酥糖13 小时前
Godot游戏练习01-第11节-显示优化,游戏背景,Shader
游戏·游戏引擎·godot
码界奇点15 小时前
基于模块化架构的Unity游戏开发框架设计与实现
java·c++·unity·架构·毕业设计·源代码管理
风酥糖17 小时前
Godot游戏练习01-第13节-粒子系统,武器攻击特效
游戏·游戏引擎·godot
V搜xhliang024620 小时前
医疗场景多模态交互
大数据·人工智能·机器人·交互·语音识别·xcode
张老师带你学20 小时前
unity船资源,快艇,帆船,游轮
科技·游戏·unity·游戏引擎·模型
C蔡博士20 小时前
Unity游戏物体渲染顺序
unity·游戏引擎·游戏开发
瑞瑞小安1 天前
Unity功能篇:PCVR开发(设备:HTC Vive Pro)更新中。。。
unity·游戏引擎