Unity 6.1下基于MetaQuestXRSimulator的自动化PlayMode测试困境
基于Meta Quest XR Simulator的Unity PlayMode自动化抓取测试实现
前提配置确认
先完成项目基础配置校验:
- 已在
Project Settings > XR Plug-in Management中启用OpenXR作为XR插件提供商 - 已在
OpenXR Settings > Interaction Profiles中勾选Meta Quest Controller Profile - 场景内已配置
XR Origin (XR SDK),并挂载Meta Quest XR Simulator组件(通常作为XR Origin的子物体,或在Camera Offset节点下)
核心实现步骤
1. 获取模拟器实例
Meta Quest XR Simulator的控制API封装在Meta.XR.Simulator命名空间下,直接通过代码获取实例即可:
using Meta.XR.Simulator; private MetaXRSimulator _simulator; void Awake() { _simulator = FindObjectOfType<MetaXRSimulator>(); if (_simulator == null) { Debug.LogError("场景中未找到MetaXRSimulator组件,请检查配置"); } }
2. 模拟手柄抓取动作
通过模拟器API直接控制手柄姿态与按键输入,实现自动抓取逻辑:
using UnityEngine; using UnityEngine.XR.OpenXR.Input; /// <summary> /// 模拟指定手柄抓取目标物体 /// </summary> /// <param name="target">待抓取的立方体</param> /// <param name="handIndex">0=左手,1=右手</param> public IEnumerator SimulateGrabAction(GameObject target, int handIndex = 1) { if (_simulator == null || target == null) yield break; // 将手柄移动到立方体前方(避免模型穿透) Vector3 targetPos = target.transform.position + Vector3.forward * 0.1f; _simulator.SetControllerPosition(handIndex, targetPos); _simulator.SetControllerRotation(handIndex, Quaternion.LookRotation(-Vector3.forward)); yield return null; // 按下扳机键(对应OpenXR的Trigger输入) string triggerInput = OpenXRInputUtility.ToInputString(OpenXRInput.Button.Trigger); _simulator.SetControllerButton(handIndex, triggerInput, true); yield return new WaitForSeconds(0.3f); // 保持抓取状态 yield return new WaitForSeconds(2f); // 释放扳机键 _simulator.SetControllerButton(handIndex, triggerInput, false); }
3. 编写PlayMode自动化测试
结合Unity Test Framework编写可自动运行的测试用例:
using NUnit.Framework; using UnityEngine; using UnityEngine.TestTools; using Meta.XR.Simulator; using UnityEngine.XR.OpenXR.Input; using UnityEngine.XR.Interaction.Toolkit; public class CubeGrabAutomationTest { private GameObject _testCube; private MetaXRSimulator _simulator; private XRController _rightController; [SetUp] public void TestSetup() { // 加载目标测试场景 UnityEngine.SceneManagement.SceneManager.LoadScene("YourTestScene"); // 获取测试所需对象 _testCube = GameObject.Find("GrabCube"); _simulator = FindObjectOfType<MetaXRSimulator>(); _rightController = FindObjectOfType<XRController>(true); } [UnityTest] public IEnumerator TestAutoGrabAndRelease() { // 等待场景初始化完成 yield return new WaitForSeconds(1f); // 执行模拟抓取逻辑 yield return SimulateGrabAction(_testCube, 1); // 验证抓取状态(假设抓取后立方体成为控制器子物体) Assert.IsTrue(_testCube.transform.parent == _rightController.transform, "立方体未被成功抓取"); // 等待释放动作完成 yield return new WaitForSeconds(0.5f); // 验证释放状态 Assert.IsNull(_testCube.transform.parent, "立方体未被成功释放"); } }
关键注意事项
- 确保立方体已挂载
XR Grab Interactable组件,并将场景中的XR Controller设置为其交互器 - 若使用自定义抓取逻辑,需调整测试中的验证条件(比如检查Rigidbody约束状态、自定义抓取标记等)
- PlayMode测试启动时,可手动初始化XR子系统避免异常:
XRGeneralSettings.Instance.Manager.InitializeLoader(); XRGeneralSettings.Instance.Manager.StartSubsystems();
内容的提问来源于stack exchange,提问作者Milan
相关产品推荐
相关产品推荐

