1. 项目概述:为什么我们要告别SteamVR?
如果你正在用Unity开发HTC Vive Pro Eye的项目,并且还在忍受着SteamVR插件那套“祖传”的绑定流程、版本兼容性问题和臃肿的运行时依赖,那么是时候考虑换条路了。我最近把一个眼动追踪交互项目从SteamVR迁移到了OpenXR,整个过程就像给项目做了一次大扫除,清爽了不少。这个标题里的“告别”,不是意气用事,而是基于一个非常明确的趋势:OpenXR正在成为跨平台XR开发的官方标准,而SteamVR正逐渐变成一个可选的、而非必须的运行时。
简单来说,这个项目就是教你如何在Unity中,绕开SteamVR插件,直接使用Unity官方的OpenXR插件来驱动HTC Vive Pro Eye,并成功激活和使用其内置的Tobii眼动追踪功能。这能带来几个立竿见影的好处:首先是依赖简化,你的项目不再强制捆绑SteamVR运行时,发布和部署更干净;其次是更好的跨平台前景,同一套代码更容易适配其他支持OpenXR的头显;最后是更现代的API和更清晰的输入系统集成。对于需要精准眼动数据的应用,比如心理研究、无障碍交互、高级UI测试或者沉浸式叙事,一个稳定、标准的配置方案至关重要。
2. 核心思路与工具选型解析
2.1 为什么是OpenXR,而不是继续用SteamVR?
SteamVR在过去几年里几乎是Unity VR开发的事实标准,它成熟、功能多,但问题也很明显。它像一个大管家,什么都管,但你也得什么都听它的。版本更新可能导致项目崩溃,它的输入系统与Unity的新输入系统(Input System)集成起来总有些别扭,而且它本质上将你锁定在了Valve的生态里。
OpenXR则不同,它是由Khronos Group(就是制定OpenGL、Vulkan标准的那个组织)主导的开放、免版税的XR API标准。它的目标是为XR硬件和软件提供统一的接口。Unity的OpenXR插件就是对这个标准的实现。选择OpenXR意味着:
- 标准化:你的项目基于行业标准,未来兼容性更有保障。
- 去耦合:应用通过OpenXR直接与头显驱动对话,不再必须经过SteamVR这个“中间商”。
- 统一输入:OpenXR定义了一套标准的输入源(如
/input/aim/pose,/input/trigger/value),Unity OpenXR插件可以将其无缝映射到Unity的Input System中,管理起来更规范。
对于HTC Vive Pro Eye,其眼动追踪硬件由Tobii提供,而Tobii也提供了支持OpenXR的运行时和SDK。这意味着我们可以构建一条“Unity App -> Unity OpenXR Plugin -> OpenXR Runtime (SteamVR或VIVE OpenXR) -> Tobii Runtime -> 硬件”的路径,从而摆脱对SteamVR插件的直接依赖。
2.2 工具链准备:你需要哪些东西?
在开始之前,请确保你拥有以下软件和硬件环境。版本号是关键,不匹配会导致各种诡异问题。
硬件:
- HTC Vive Pro Eye头显及定位器(1.0或2.0均可)。
- 配套的控制器。
软件环境:
- Unity版本:强烈推荐使用Unity 2021.3 LTS或更高版本。这些版本对OpenXR的支持最成熟。我是在Unity 2022.3 LTS上完成的,非常稳定。
- Unity模块:在安装Unity时或通过Unity Hub,确保安装了“Windows Build Support (IL2CPP)”和“Android Build Support”(如果需要)。OpenXR插件需要这些模块。
- SteamVR:是的,你仍然需要安装Steam和SteamVR。但请注意,它的角色从“开发插件依赖”变成了“可选的OpenXR运行时之一”。请确保SteamVR为最新版本。
- VIVE OpenXR运行时 (关键!):这是HTC官方提供的OpenXR运行时。对于Vive系列设备,使用它通常比用SteamVR作为OpenXR运行时更稳定、功能支持更直接。你需要从VIVE开发者网站下载并安装。
- Tobii XR SDK:这是启用眼动追踪的核心。你需要从Tobii官方开发者网站下载适用于Unity的Tobii XR SDK。注意选择支持OpenXR的版本。
Unity插件(通过Package Manager安装):
- XR Plugin Management:管理XR插件的基础包。
- OpenXR Plugin:Unity官方的OpenXR实现。
- XR Interaction Toolkit (可选但推荐):用于快速构建交互,它已经很好地集成了新的输入系统。
- Tobii XR SDK:将下载的SDK(通常是一个
.unitypackage)导入项目,或者如果Tobii已将其上架Unity Asset Store,也可以从Package Manager添加。
3. 详细配置步骤与实操要点
3.1 第一步:创建项目与基础插件安装
首先,使用Unity 2022.3 LTS创建一个新的3D项目(URP或Built-in渲染管线均可,根据项目需求选择。URP对VR性能更友好)。项目创建后,立即打开Window -> Package Manager。
- 在Package Manager中,切换到“Unity Registry”。
- 搜索并安装“XR Plugin Management”。
- 搜索并安装“OpenXR Plugin”。安装过程中,可能会提示你安装相关的依赖包,如“Windows XR Plugin”,同意即可。
- (推荐)搜索并安装“XR Interaction Toolkit”。这个工具包能极大简化控制器交互、射线交互等的开发。
安装完成后,Unity可能会要求你重启编辑器。重启后,你会看到Project Settings里多出了XR相关的设置项。
3.2 第二步:配置XR Plugin Management与OpenXR
这是整个流程的核心,一步错可能导致头显无法识别或输入失灵。
- 打开Edit -> Project Settings,然后选择XR Plug-in Management。
- 在“PC Standalone”标签页下(因为我们主要针对PC VR),你会看到已安装的XR插件列表。找到“OpenXR”并勾选它。
- 勾选OpenXR后,其下方会出现“OpenXR”的子设置项,点击进入。
OpenXR详细设置:
- Interaction Profiles (交互配置文件):这是映射输入的关键。点击“+”号添加交互配置文件。
- 对于Vive控制器,你需要添加“HTC Vive Controller Profile”。
- 为了更广泛的兼容性,也可以添加“Microsoft Motion Controller Profile”,但Vive Profile优先级更高。
- 如果你使用了XR Interaction Toolkit,它可能会自动为你添加一些Profile。
- Render Mode:选择“Single Pass Instanced”。这是VR渲染的标准和高效模式。
- Depth Submission Mode:通常保持默认的“Depth 16 Bit”即可。
关键提示:配置完成后,不要急于戴上头显测试。先确保你的默认OpenXR运行时设置正确。
3.3 第三步:设置正确的OpenXR运行时(避坑关键)
Windows系统可以安装多个OpenXR运行时(如SteamVR、VIVE OpenXR、Oculus Runtime等),但一次只能激活一个。我们需要将VIVE OpenXR运行时设为默认。
- 打开Windows“开始”菜单,搜索“设置OpenXR运行时”或“Configure OpenXR Runtime”。这个应用通常随VIVE OpenXR运行时或SteamVR安装。
- 运行该应用。你会看到一个列表,显示所有已安装的OpenXR运行时。
- 从列表中选择“VIVE OpenXR Runtime”或类似的选项(具体名称可能因版本略有不同),然后点击“设置为活动”或“Set as Active”。
- 确认更改。
实操心得:很多“头显无法识别”或“控制器没反应”的问题,都源于运行时设置错误。如果你之前主要用SteamVR开发,这里很可能默认是SteamVR。务必将其切换到VIVE OpenXR。你可以通过这个设置面板快速切换,方便在不同项目间测试。
3.4 第四步:导入与配置Tobii XR SDK
- 将你从Tobii官网下载的
TobiiXR.unitypackage导入项目(Assets -> Import Package -> Custom Package)。 - 导入后,在Project Settings中,你会找到一个新的设置项“Tobii XR”或“Tobii XR Settings”。
- 进入Tobii XR设置,确保“Enable Tobii XR”被勾选。
- 在“XR Platform Settings”中,选择“OpenXR”作为XR Provider。这是告诉Tobii SDK我们使用OpenXR路径的关键。
- 检查其他设置,如Gaze Ray Origin(通常使用眼睛中心)、校准类型等,保持默认通常即可。
与OpenXR的集成检查: Tobii XR SDK for OpenXR应该会自动向Unity的OpenXR子系统注册眼动追踪功能。你可以在Edit -> Project Settings -> XR Plug-in Management -> OpenXR的“Features”列表里查看,应该能看到眼动追踪相关的特性(如eye_gaze_interaction)已被列出并启用。如果没有,请检查Tobii SDK的导入和版本是否支持你的Unity版本。
3.5 第五步:编写代码获取眼动数据
环境配置好后,就可以在脚本中获取眼动数据了。Tobii XR SDK提供了几种访问数据的方式,这里介绍最常用的两种。
方法一:通过Tobii XR的GazeData API(直接)
using Tobii.XR; using UnityEngine; public class SimpleGazeTracker : MonoBehaviour { void Update() { // 获取当前帧的凝视数据 var gazeData = TobiiXR.GetEyeTrackingData(TobiiXR_TrackingSpace.World); // gazeData.GazeRay 是世界空间中的射线,包含Origin(起点)和Direction(方向) if (gazeData.GazeRay.IsValid) { RaycastHit hit; if (Physics.Raycast(gazeData.GazeRay.Origin, gazeData.GazeRay.Direction, out hit)) { Debug.Log($"你正在看: {hit.collider.gameObject.name}"); // 在这里处理凝视交互,例如高亮物体 } } // 你还可以获取瞳孔直径、眼睛开合度等数据 // var leftPupilDiameter = gazeData.Left.PupilDiameter; // var isLeftEyeBlinking = gazeData.Left.IsBlinking; } }方法二:通过Unity的Input System(标准化)这是更推荐的方式,因为它与Unity的新输入系统集成,更符合OpenXR的哲学。
- 首先,确保在Edit -> Project Settings -> Input System Package中,将“Active Input Handling”设置为“Both”或“Input System Package (New)”。
- Tobii SDK会通过OpenXR向Input System注册一个“Eye Gaze”设备。
- 你可以通过以下方式访问:
using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.XR; public class InputSystemGazeTracker : MonoBehaviour { public void OnGaze(InputAction.CallbackContext context) { // 这种方式通常用于事件驱动,但凝视数据更适合在Update中持续获取 } void Update() { var eyeGazeDevice = InputSystem.GetDevice<UnityEngine.InputSystem.XR.EyeGaze>(); if (eyeGazeDevice != null && eyeGazeDevice.enabled) { // 读取凝视位置和旋转 var gazePosition = eyeGazeDevice.position.ReadValue(); var gazeRotation = eyeGazeDevice.rotation.ReadValue(); // 注意:这里的数据可能是本地空间(相对于头显)的,需要根据你的跟踪空间设置进行转换 // 更常见的做法是直接使用TobiiXR.GetEyeTrackingData,因为它已经处理了空间转换。 } } }注意事项:对于眼动追踪,方法一(直接使用TobiiXR API)通常更简单直接,因为SDK已经为你处理了坐标系转换、数据平滑等复杂问题。方法二(Input System)的集成度在眼动追踪上可能不如手柄控制器那么完善,但它代表了未来的方向。
4. 构建、部署与真机测试流程
4.1 项目构建设置
- 打开File -> Build Settings。
- 确保“PC, Mac & Linux Standalone”被选中,且“Target Platform”为“Windows”。
- 将你的主场景拖入Scenes In Build列表。
- 点击“Player Settings...”,在Player Settings窗口中:
- 检查“XR Plug-in Management”确保OpenXR已启用。
- 在“Resolution and Presentation”下,可以设置全屏模式等。
- (重要)在“Other Settings”部分,将“Color Space”设置为“Linear”。线性色彩空间对于VR渲染的视觉准确性非常重要。
- 点击Build,生成一个.exe文件。
4.2 真机测试步骤与校准
- 确保头显、定位器已正确连接并开启。
- 运行构建好的.exe程序。
- 戴上头显。如果一切配置正确,你应该能直接进入VR场景,并且手柄可以正常被识别和追踪。
- 眼动校准:这是使用眼动追踪前必须的步骤。通常,Tobii SDK会提供一个内置的校准流程。
- 一种常见的方式是,在场景中创建一个
GazeCalibration脚本或使用Tobii SDK提供的Prefab。 - 在应用启动后,或者在某个设置菜单中,调用
TobiiXR.StartCalibration()来启动校准流程。 - 用户需要跟随屏幕上的校准点(通常是一个移动的小点)进行凝视,直到所有校准点完成。
- 校准数据会保存在本地,下次启动时无需重复校准,除非用户换人使用或觉得精度下降。
- 一种常见的方式是,在场景中创建一个
- 校准完成后,你就可以测试上面的凝视追踪代码了。在场景中放置一些物体,看看凝视射线是否能正确击中它们。
5. 常见问题排查与性能优化
5.1 问题排查速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 头显无显示/黑屏 | 1. OpenXR运行时未设置为VIVE OpenXR。 2. Unity中OpenXR插件未启用。 3. 显卡驱动过旧。 | 1. 运行“设置OpenXR运行时”,切换为VIVE OpenXR并设为活动。 2. 检查Project Settings -> XR Plug-in Management -> PC Standalone,确保OpenXR已勾选。 3. 更新NVIDIA/AMD显卡驱动至最新版本。 |
| 手柄无法追踪或输入无效 | 1. 交互配置文件(Interaction Profile)未添加或错误。 2. SteamVR未运行或基站未追踪到。 3. 使用了旧版输入系统。 | 1. 在OpenXR设置中,确认添加了“HTC Vive Controller Profile”。 2. 确保SteamVR已运行(即使运行时是VIVE OpenXR,基站追踪有时仍需SteamVR服务),且手柄被定位器看到。 3. 尝试在Player Settings中切换到“Input System Package (New)”。 |
| 眼动数据无效或为0 | 1. Tobii XR SDK未启用或配置错误。 2. 未进行眼动校准。 3. 用户佩戴位置不正确,眼动相机未捕捉到眼睛。 | 1. 检查Project Settings -> Tobii XR,确保已启用且XR Provider为OpenXR。 2. 在应用中集成并执行眼动校准流程。 3. 提示用户调整头显佩戴位置,确保眼睛在镜片中心区域。 |
| 编译错误,找不到XR相关命名空间 | 1. XR Plugin Management或OpenXR插件未正确安装。 2. 脚本编译顺序问题。 | 1. 通过Package Manager重新安装相关插件,并重启Unity。 2. 确保脚本中引用了正确的命名空间,如 using UnityEngine.XR。 |
| 应用运行时崩溃 | 1. 多个XR运行时冲突。 2. 显卡驱动或系统问题。 3. Unity版本与插件版本不兼容。 | 1. 确保只激活一个OpenXR运行时(VIVE OpenXR)。关闭Oculus服务等。 2. 使用DxDiag检查系统,更新驱动。 3. 回退到Unity LTS版本和插件已知稳定的版本组合。 |
5.2 性能优化与调试技巧
- 使用XR Stats窗口:在Unity编辑器中,打开Window -> Analysis -> XR Stats。这个窗口在运行时会显示关键的VR性能指标,如FPS、CPU/GPU时间、渲染分辨率等。确保你的应用能稳定维持在头显的刷新率(Vive Pro Eye是90Hz)。
- 单通道实例化渲染:务必在OpenXR设置中使用“Single Pass Instanced”,这是VR渲染性能的基石。
- 眼动追踪的性能考量:眼动追踪本身CPU开销很低。但基于凝视的交互(如大量物体的实时高亮)可能带来性能压力。考虑使用空间划分(如四叉树、八叉树)来优化凝视射线检测,或者将检测频率从每帧降低到每秒几次。
- 调试眼动射线:在开发时,可视化凝视射线非常有用。可以在
Update中画一条Debug射线:
这样在Scene视图中就能看到一条绿色的线代表用户的视线方向。var gazeData = TobiiXR.GetEyeTrackingData(TobiiXR_TrackingSpace.World); if (gazeData.GazeRay.IsValid) { Debug.DrawRay(gazeData.GazeRay.Origin, gazeData.GazeRay.Direction * 10f, Color.green); } - 数据平滑与过滤:原始眼动数据会有微小的抖动。Tobii SDK通常内置了滤波算法。如果需要更精细的控制,可以查阅SDK文档,看是否提供了数据平滑的参数配置,或者自己在代码中对
GazeRay.Direction进行低通滤波。
迁移到OpenXR的初期可能会遇到一些配置上的挑战,但一旦打通,整个开发流程会变得更加清晰和现代。它剥离了不必要的依赖,让你更专注于应用逻辑本身,尤其是对于HTC Vive Pro Eye这样具备特殊硬件的设备,标准化的OpenXR路径提供了更可靠的长期支持。