Unreal 中的手部跟踪

手部跟踪系统使用用户的手掌和手指作为输入。 每根手指、整个手掌和手势的位置和旋转数据均可用。 从 Unreal 4.26 开始,手部跟踪基于 Unreal HeadMountedDisplay 插件,并在所有 XR 平台和设备上使用公共 API。 Windows Mixed Reality 和 OpenXR 系统的功能相同。

手势

使用手势,你可以跟踪和使用用户的手和手指作为输入,可在蓝图和 C++ 中访问这些数据。 Unreal API 以坐标系统的形式发送数据,时钟周期与 Unreal Engine 同步。

Hand skeleton image with joints overlayHand Skeleton

该层次结构由 EHandKeypoint 枚举描述:

Image of hand keypoint bluprint options

你可以使用“获取运动控制器数据”函数从用户手中获得所有这些数据。 该函数返回一个 XRMotionControllerData 结构。 下面是蓝图脚本示例,它分析 XRMotionControllerData 结构以获取手关节位置,并在每个关节位置绘制调试坐标系统。

Blueprint of get gaze data function connected to line trace by channel function

务必要检查该结构是否有效以及它是否为手。 否则,在访问位置、旋转和半径数组时,可能会获得未定义的行为。

手势使用实时链接插件显示给动画。

如果 Windows Mixed Reality 和实时链接插件已启用:

  1. 选择“窗口”>“实时链接”,打开“实时链接编辑器”窗口
  2. 选择“源”并启用“Windows Mixed Reality 手部跟踪源”

Live Link Source

启用源并打开动画资产后,展开“预览场景”选项卡中的“动画”部分可看到其他选项。

Live Link Animation

手动画层次结构与 EWMRHandKeypoint 中相同。 动画可以使用 WindowsMixedRealityHandTrackingLiveLinkRemapAsset 重定向

Live Link Animation 2

还可以在编辑器中将它作为子类:

Live Link Remap

手部网格

重要

手部网格需要 OpenXR。

必须使用 Microsoft OpenXR 插件,可从 Unreal MarketplaceGitHub 获得。

手部网格作为跟踪几何

重要

若要在 OpenXR 中将手部网格作为跟踪几何获取,需要调用已启用跟踪几何的“设置使用手部网格”

若要启用该模式,应调用已启用跟踪几何的“设置使用手部网格”

Blueprint of event begin play connected to set use hand mesh function with enabled tracking geometry mode

注意

不可能同时启用这两种模式。 如果启用一个,则会自动禁用另一个。

访问手部网格数据

Hand Mesh

在可以访问手部网格数据之前,你需要:

  • 选择“ARSessionConfig”资产,展开“AR 设置”->“世界映射”设置,然后选中“根据跟踪几何生成网格数据”

下面是默认的网格参数:

  1. 使用网格数据进行遮挡
  2. 为网格数据生成碰撞
  3. 为网格数据生成导航网格
  4. 在线框中呈现网格数据 - 显示生成网格的调试参数

这些参数值用作空间映射网格和手部网格默认值。 你可以在任何网格的蓝图或代码中随时对其进行更改。

C++ API 参考

使用 EEARObjectClassification 查找所有可跟踪对象中的手部网格值。

enum class EARObjectClassification : uint8
{
    // Other types
	HandMesh,
};

当系统检测到任何可跟踪对象(包括手部网格)时,将调用以下委托。

class FARSupportInterface
{
    public:
    // Other params
	DECLARE_AR_SI_DELEGATE_FUNCS(OnTrackableAdded)
	DECLARE_AR_SI_DELEGATE_FUNCS(OnTrackableUpdated)
	DECLARE_AR_SI_DELEGATE_FUNCS(OnTrackableRemoved)
};

请确保委托处理程序遵循下面的函数签名:

void UARHandMeshComponent::OnTrackableAdded(UARTrackedGeometry* Added)

可以通过 UARTrackedGeometry::GetUnderlyingMesh 访问网格数据:

UMRMeshComponent* UARTrackedGeometry::GetUnderlyingMesh()

蓝图 API 参考

若要在蓝图中使用手部网格:

  1. 将“ARTrackableNotify”组件添加到蓝图角色

ARTrackable Notify

  1. 请转到“详细信息”面板,展开“事件”部分

ARTrackable Notify 2

  1. 在添加/更新/删除跟踪几何时,使用以下事件图像中的节点进行覆盖:

On ARTrackable Notify

OpenXR 中的手部网格可视化效果

可视化手部网格的建议方法是将 Epic 的 XRVisualization 插件与 Microsoft OpenXR plugin 插件结合使用。

然后,在蓝图编辑器中,应使用 Microsoft OpenXR 插件中的“设置使用手部网格”函数,并将“已启用 XRVisualization”作为参数:

Blueprint of event begin play connected to set use hand mesh function with enabled xrvisualization mode

若要管理呈现过程,应使用 XRVisualization 中的“呈现运动控制器”

Blueprint of get motion controller data function connected to render motion controller function

结果:

Image of digital hand overlayed on a real human hand

如果需要更复杂的内容(例如使用自定义着色器绘制手部网格),需要将网格作为跟踪几何。

手部射线

获取手势适用于近距交互,例如抓取对象或按按钮。 但是,有时你需要使用距离用户较远的全息影像。 这可以通过手部射线实现,可在 C++ 和蓝图中用作指向设备。 你可以将射线从手绘制到某个远点,在 Unreal 光线跟踪的一些帮助下,选择其他情况下无法触及的全息影像。

重要

由于所有函数结果都会随每个帧更改,因此它们都是可调用的。 有关纯函数、非纯函数或可调用函数的信息,请参阅函数的蓝图用户 guid。

若要获取手部射线数据,应使用上一部分中的“获取运动控制器数据”函数。 返回的结构包含两个参数,你可以用来创建一个手部射线 - 目标位置和目标旋转。 这些参数形成由肘部定向的射线。 应使用这些参数,并找到所指向的全息影像。

以下示例用于确定手部射线是否命中小组件并设置自定义命中结果:

Blueprint of get motion controller data function

笔势

HoloLens 2 跟踪空间手势,这意味着你可以捕获这些手势作为输入。 手势跟踪基于订阅模型。 应使用“配置手势”函数来告知设备要跟踪的手势。有关手势的更多详细信息,请参阅 HoloLens 2 基本用法文档。

Windows Mixed Reality

Blueprint of event begin play connected to configure gestures function

然后,应添加代码来订阅以下事件:

Blueprint of Windows spatial input hold, tap, and left manipulation gesturesScreenshot of Windows spatial input tap gesture options in the details panel

OpenXR

在 OpenXR 中,手势事件通过输入管道进行跟踪。 使用手势交互,设备可以自动识别“点击并按住”手势,但不能识别其他手势。 它们命名为 OpenXRMsftHandInteraction 选择和抓握映射。 无需启用订阅,应在 Project Settings/Engine/Input 中声明事件,如下所示:

Screenshot of the OpenXR action mappings

下一个开发检查点

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

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

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