凝视输入

混合现实应用中的凝视输入旨在用于确定用户正在注视什么。 当设备上的眼动跟踪相机与 Unreal 世界空间中的射线匹配时,便已获得了用户的视线数据。 凝视可以在蓝图和 C++ 中使用,是对象交互、路线查找和相机控制等机制的核心功能。

启用眼动跟踪

  • 在“项目设置”>“HoloLens”中启用“视线输入”功能

Screenshot of HoloLens project setting capabilities with gaze input highlighted

  • 创建一个新的执行组件并将其添加到场景中

注意

Unreal 中的 HoloLens 眼动跟踪仅支持双眼发出的一条凝视射线。 不支持需要两条射线的立体跟踪。

使用眼动跟踪

首先,使用 IsEyeTrackerConnected 函数检查设备是否支持眼动跟踪。 如果该函数返回 true,请调用 GetGazeData 来确定用户的眼睛正在注视当前帧中的哪个位置

Blueprint of the Is Eye Tracking Connected function

注意

凝视点和置信度值在 HoloLens 上不可用。

使用线迹中的凝视原点和方向来准确找出用户正在注视的位置。 凝视值是一个向量,从凝视原点开始,到原点加上凝视方向乘以线迹距离的值结束:

Blueprint of the Get Gaze Data function

获取头部方向

还可以使用头盔式显示器 (HMD) 的旋转来表示用户头部的方向。 可以在不启用“凝视输入”功能的情况下获取用户的头部方向,但无法获取任何眼动跟踪信息。 添加对蓝图的引用作为世界上下文,以获取正确的输出数据:

注意

只能在 Unreal 4.26 和更高版本中获取 HMD 数据。

Blueprint of the Get HMDData function

使用 C++

  • 在游戏的 build.cs 文件中,将 EyeTracker 添加到 PublicDependencyModuleNames 列表中
PublicDependencyModuleNames.AddRange(
    new string[] {
        "Core",
        "CoreUObject",
        "Engine",
        "InputCore",
        "EyeTracker"
});
  • 在“文件”/“新建 C++ 类”中,创建名为 EyeTracker 的新 C++ 执行组件
    • Visual Studio 解决方案将打开新的 EyeTracker 类。 使用新的 EyeTracker 执行组件进行生成和运行操作,以打开 Unreal 游戏。 在“放置执行组件”窗口中搜索“EyeTracker”,并将该类拖放到游戏窗口中以将其添加到项目

Screenshot of an actor with the place actor window open

  • 在 EyeTracker.cpp 中,为 EyeTrackerFunctionLibrary 和 DrawDebugHelpers 添加 include 语句
#include "EyeTrackerFunctionLibrary.h"
#include "DrawDebugHelpers.h"

在尝试获取任何凝视数据之前,请检查设备是否支持使用 UEyeTrackerFunctionLibrary::IsEyeTrackerConnected 进行眼动跟踪。 如果支持眼动跟踪,请从 UEyeTrackerFunctionLibrary::GetGazeData 中查找线迹的射线起点和终点。 从那里,可以生成一个凝视向量并将其内容传递给 LineTraceSingleByChannel,以调试任何射线命中结果

void AEyeTracker::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    if(UEyeTrackerFunctionLibrary::IsEyeTrackerConnected())
    {
        FEyeTrackerGazeData GazeData;
        if(UEyeTrackerFunctionLibrary::GetGazeData(GazeData))
        {
            FVector Start = GazeData.GazeOrigin;
            FVector End = GazeData.GazeOrigin + GazeData.GazeDirection * 100;

            FHitResult Hit Result;
            if (GWorld->LineTraceSingleByChannel(HitResult, Start, End, ECollisionChannel::ECC_Visiblity))
            {
                DrawDebugCoordinateSystem(GWorld, HitResult.Location, FQuat::Identity.Rotator(), 10);
            }
        }
    }
}

下一个开发检查点

如果你遵循我们规划的 Unreal 开发历程,则你处于探索 MRTK 核心基础知识的过程之中。 从这里,你可以继续了解下一部分基础知识:

或跳转到混合现实平台功能和 API:

你可以随时返回到 Unreal 开发检查点

另请参阅