You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何从TrackedPoseDriver获取面部追踪的centerEyeRotation数据

获取ARKit面部追踪的实时centerEyeRotation数据

我在Unity中用ARKit实现了iOS设备上的面部追踪,功能运行正常,但没法获取面部追踪生成的实时centerEyeRotation数据。我试过两种方法都没成功:

尝试的第一种方法

这段代码获取的TrackedPoseDriver返回的始终是主相机自身的数据:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class getTrackedPoseDriver : MonoBehaviour
{
    bool found;
    MonoBehaviour mbTrackingPose;
    MonoBehaviour mb;

    void Start()
    {
        Component[] components = Camera.main.GetComponents(typeof(MonoBehaviour));
        found = false;
        foreach (Component component in components)
        {
            string name = component.ToString();
            mb = (MonoBehaviour)component;
            if (name.Contains("UnityEngine.InputSystem.XR.TrackedPoseDriver"))
            {
                mbTrackingPose = mb;
                found = true;
                Debug.Log(found);
                Debug.Log(mbTrackingPose.name);
                break;
            }
        }
    }

    void Update()
    {
        Debug.Log(mbTrackingPose.transform.rotation.y);
    }
}

尝试的第二种方法

确认XRNode.CenterEye有效,但device.TryGetFeatureValue无法获取到centerEyePosition(更不用说旋转数据):

using System.Collections;
using System.Collections;
using UnityEngine;
using UnityEngine.XR;

public class centerEyeRotation : MonoBehaviour
{
    Quaternion centEyeRot;
    Vector3 centEyePos;
    bool tryGet;

    void Start()
    {
        tryGet = false;

        InputDevice device = InputDevices.GetDeviceAtXRNode(XRNode.CenterEye);

        if (device.isValid)
        {
            Debug.Log("Device is valid");
            if (device.TryGetFeatureValue(CommonUsages.centerEyePosition, out centEyePos))
                tryGet = true;
            Debug.Log("centerEyePosition found");
        }
    }
}

正确获取centerEyeRotation的方法

方法一:直接调用ARKit面部子系统(推荐)

ARKit的面部眼动数据属于XRFaceSubsystem的原生输出,这是最可靠的获取方式,因为XRNode.CenterEye更多针对VR头显场景,面部追踪的眼动数据不会自动填充到这个节点。

代码示例:

using UnityEngine;
using UnityEngine.XR.ARKit;
using UnityEngine.XR.ARFoundation;

public class FaceEyeRotationGetter : MonoBehaviour
{
    [SerializeField] private ARFaceManager faceManager;
    private ARKitFaceSubsystem arkitFaceSubsystem;

    void Start()
    {
        // 获取ARKit面部追踪子系统实例
        arkitFaceSubsystem = faceManager.subsystem as ARKitFaceSubsystem;
    }

    void Update()
    {
        if (arkitFaceSubsystem == null || !arkitFaceSubsystem.running)
            return;

        // 遍历所有追踪到的面部(通常只有一个)
        foreach (var face in arkitFaceSubsystem.trackables)
        {
            // 获取左右眼的旋转数据
            if (face.TryGetEyePose(ARKitEye.Left, out var leftEyePose))
            {
                Debug.Log("左眼旋转: " + leftEyePose.rotation);
            }
            if (face.TryGetEyePose(ARKitEye.Right, out var rightEyePose))
            {
                Debug.Log("右眼旋转: " + rightEyePose.rotation);
            }

            // 如果需要双眼平均的中心眼旋转
            Quaternion centerEyeRot = Quaternion.Lerp(leftEyePose.rotation, rightEyePose.rotation, 0.5f);
            Debug.Log("中心眼旋转: " + centerEyeRot);
        }
    }
}

使用说明:

  • 确保场景中存在ARFaceManager组件,将其拖入脚本的faceManager字段
  • 该方法直接读取ARKit原生眼动数据,实时性和准确性有保障

方法二:修正InputDevice获取逻辑

如果一定要用XRNode.CenterEye,需要注意两个关键点:

  1. 不能只在Start()中获取一次设备,数据可能在运行时才初始化
  2. 必须在每一帧尝试获取数据,而不是仅在启动时

修正后的代码:

using UnityEngine;
using UnityEngine.XR;

public class CenterEyeRotationGetter : MonoBehaviour
{
    void Update()
    {
        InputDevice centerEyeDevice = InputDevices.GetDeviceAtXRNode(XRNode.CenterEye);
        
        if (centerEyeDevice.isValid)
        {
            // 获取中心眼旋转
            if (centerEyeDevice.TryGetFeatureValue(CommonUsages.centerEyeRotation, out Quaternion centerEyeRot))
            {
                Debug.Log("CenterEye旋转: " + centerEyeRot);
            }
            // 同时获取位置(如果需要)
            if (centerEyeDevice.TryGetFeatureValue(CommonUsages.centerEyePosition, out Vector3 centerEyePos))
            {
                Debug.Log("CenterEye位置: " + centerEyePos);
            }
        }
    }
}

注意:这种方法在ARKit面部追踪场景下兼容性较差,不推荐作为首选方案。

你之前的方法失败原因

  • 第一种方法:你获取的是主相机上的TrackedPoseDriver,这个组件的作用是驱动相机跟随XR设备,它的transform数据就是相机自身的,和面部眼动无关
  • 第二种方法:仅在Start()中尝试一次获取数据,而面部追踪的设备数据可能在启动后才完成初始化,且没有实时更新获取逻辑

内容的提问来源于stack exchange,提问作者cluelessButCurious

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 08:35:21