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

相关推荐
虾球xz1 分钟前
游戏引擎学习第292天:实现蛇
c++·学习·游戏引擎
DanmF--1 分钟前
Protobuf协议生成和使用
网络·unity·c#·游戏引擎·游戏程序
AgilityBaby2 分钟前
关于在Unity项目中使用Post Processing插件打包到web端出现的问题
3d·unity·游戏引擎
FAREWELL000759 小时前
Unity学习总结篇(1)关于各种坐标系
学习·unity·c#·游戏引擎
一只码代码的章鱼9 小时前
Spring Boot- 2 (数万字入门教程 ):数据交互篇
spring boot·后端·交互
Quieeeet14 小时前
【搭建Node-RED + MQTT Broker实现AI大模型交互】
人工智能·物联网·交互
与火星的孩子对话18 小时前
Unity3D开发AI桌面精灵/宠物系列 【六】 人物模型 语音口型同步 LipSync 、梅尔频谱MFCC技术、支持中英文自定义编辑- 基于 C# 语言开发
人工智能·unity·c#·游戏引擎·宠物·lipsync
程序猿阿伟18 小时前
《云端共生体:Flutter与AR Cloud如何改写社交交互规则》
flutter·ar·交互
Code哈哈笑19 小时前
【基于Spring Boot 的图书购买系统】深度讲解 用户注册的前后端交互,Mapper操作MySQL数据库进行用户持久化
数据库·spring boot·后端·mysql·mybatis·交互
虾球xz21 小时前
游戏引擎学习第293天:移动Familiars
c++·学习·游戏引擎