/*
* ==================================================================================================================
*
* 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("是否啟用焦點(diǎn)?")] private bool focusEnabled = true;
/// <summary>
/// 是否為啟用了焦點(diǎn)
/// </summary>
public virtual bool FocusEnabled
{
get => focusEnabled;
set => focusEnabled = value;
}
/// <summary>
/// 此對(duì)象當(dāng)前是否有焦點(diǎn)
/// </summary>
public virtual bool HasFocus => FocusEnabled && Focusers.Count > 0;
/// <summary>
/// 當(dāng)前聚焦此對(duì)象的列表
/// </summary>
public List<IMixedRealityPointer> Focusers { get; } = new(0);
/// <summary>
/// 焦點(diǎn)進(jìn)入
/// </summary>
public virtual void OnFocusEnter(FocusEventData eventData)
{
}
/// <summary>
/// 焦點(diǎn)退出
/// </summary>
public virtual void OnFocusExit(FocusEventData eventData)
{
}
public virtual void OnBeforeFocusChange(FocusEventData eventData)
{
//如果是新的目標(biāo)對(duì)象,將指針添加到焦點(diǎn)列表。
if (eventData.NewFocusedObject == gameObject)
{
eventData.Pointer.FocusTarget = this;
Focusers.Add(eventData.Pointer);
}
//如果是舊的聚焦目標(biāo)對(duì)象,從列表中刪除指針。
else if (eventData.OldFocusedObject == gameObject)
{
Focusers.Remove(eventData.Pointer);
//如果沒有新的焦點(diǎn)目標(biāo),從指針中清除焦點(diǎn)目標(biāo)。
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("可配置的持續(xù)時(shí)間,用于在用戶查注釋目標(biāo)的時(shí)間超過此持續(xù)時(shí)間時(shí)觸發(fā)事件。")] [SerializeField] [Range(0, 20)]
private float timeToTriggerDwellInSec = 5;
/// <summary>
/// 停留時(shí)間
/// </summary>
private DateTime _dwellTimer;
/// <summary>
/// 是否持續(xù)注視
/// </summary>
private bool _isDwelling = false;
/// <summary>
/// 是否注視
/// </summary>
private bool _hadFocus = false;
/// <summary>
/// 處理光標(biāo)進(jìn)入目標(biāo)時(shí)的突出顯示目標(biāo)。
/// </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)
{
//如果注視新的目標(biāo)對(duì)象,將指針添加到焦點(diǎn)列表。
if (eventData.NewFocusedObject == gameObject &&
eventData.Pointer.InputSourceParent.SourceType == InputSourceType.Eyes)
{
eventData.Pointer.FocusTarget = this;
Focusers.Add(eventData.Pointer);
}
//如果注視是舊的聚焦目標(biāo)對(duì)象,從列表中刪除指針。
else if (eventData.OldFocusedObject == gameObject)
{
Focusers.Remove(eventData.Pointer);
// 如果沒有新目標(biāo),從指針中清除焦點(diǎn)目標(biāo)
if (eventData.NewFocusedObject == null)
{
eventData.Pointer.FocusTarget = null;
}
}
}
/// <summary>
///一旦眼睛凝視射線開始與該目標(biāo)的碰撞體接觸,就會(huì)觸發(fā)。
/// </summary>
protected virtual void OnEyeFocusStart()
{
}
/// <summary>
/// 在眼睛凝視射線與該目標(biāo)的碰撞體持續(xù)接觸時(shí)觸發(fā)。
/// </summary>
protected virtual void OnEyeFocusStay()
{
}
/// <summary>
///一旦眼睛凝視射線停止與該目標(biāo)的碰撞體,就會(huì)觸發(fā)。
/// </summary>
protected virtual void OnEyeFocusStop()
{
}
/// <summary>
/// 一旦眼睛凝視射線與該目標(biāo)的碰撞體接觸指定時(shí)間后觸發(fā)。
/// </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);
}
}
在場(chǎng)景中新建一個(gè)物體,將EyeTrackingTest組件掛載到新建的物體上就可以了文章來源地址http://www.zghlxwxcb.cn/news/detail-721757.html
文章來源:http://www.zghlxwxcb.cn/news/detail-721757.html
到了這里,關(guān)于Unity MRTK Hololens2眼動(dòng)交互的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!