基于MRTK将Hololens项目迁移至Oculus Quest 2的空间锚点问题求助
将Hololens MRTK项目迁移至Oculus Quest 2:实现控制器扳机创建空间锚点并获取Transform
问题概述
原项目为Hololens平台,基于MRTK+Vuforia实现物体识别,现迁移至Oculus Quest 2,因无法使用摄像头识别,改用空间锚点实现虚拟物体与物理空间对齐,目前遇到以下问题:
- 参考教程实现的空间锚点代码无法正常运行
- 运行时出现警告:
OVRSpatialAnchor requires the GameObject to have a OVRTrackedPose component, or be a child of a GameObject with one. - 无法实现通过Oculus控制器扳机键创建锚点并获取其Transform
当前代码
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class SpatialAnchorsManager : MonoBehaviour { [SerializeField] GameObject anchorobject; [SerializeField] ulong id; OVRSpatialAnchor anchor; private void Start() { StartCoroutine(createanchor()); } private void Update() { if (Input.GetKeyDown(KeyCode.V)) { //OVRPlugin.CreateSpatialAnchor(); } } IEnumerator createanchor() { var anchor = gameObject.AddComponent<OVRSpatialAnchor>(); yield return new WaitUntil(() => anchor.Created); var anchors = new HashSet<OVRSpatialAnchor> { anchor }; //anchorobject = anchor.gameObject; yield return null; } }
已完成配置
- 配置了MRTK透视输入相关设置
- 对OVRCameraRig进行了适配修改
解决方案
1. 修复空间锚点警告问题
警告核心原因是OVRSpatialAnchor必须挂载在带有OVRTrackedPose组件的GameObject上,或作为其子物体。建议将锚点创建在控制器的跟踪节点下(比如右手控制器的OVRController物体),确保锚点位置能被正确跟踪。
2. 替换键盘输入为Oculus控制器扳机检测
使用MRTK输入系统检测扳机键按下,保持MRTK功能一致性,也可使用OVR原生API。
3. 正确获取锚点Transform
锚点创建成功后,直接通过anchor.transform即可获取其Transform信息。
修改后的完整代码
using System.Collections; using UnityEngine; using Microsoft.MixedReality.Toolkit.Input; public class SpatialAnchorsManager : MonoBehaviour { [SerializeField] private Transform controllerAnchorPoint; // 拖拽绑定到Oculus控制器的跟踪节点(如OVRController-Right) [SerializeField] private GameObject anchorobject; private OVRSpatialAnchor currentAnchor; private void OnEnable() { // 订阅MRTK控制器输入事件 CoreServices.InputSystem?.RegisterHandler<IMixedRealityPointerHandler>(this); } private void OnDisable() { CoreServices.InputSystem?.UnregisterHandler<IMixedRealityPointerHandler>(this); } // 处理MRTK控制器扳机点击事件 public void OnPointerClicked(MixedRealityPointerEventData eventData) { // 响应Select动作(对应控制器扳机键) if (eventData.MixedRealityInputAction == MixedRealityInputAction.Select) { StartCoroutine(CreateSpatialAnchorAtController()); } } private IEnumerator CreateSpatialAnchorAtController() { // 销毁已有锚点 if (currentAnchor != null) { Destroy(currentAnchor.gameObject); } // 创建锚点物体,绑定到控制器跟踪节点 GameObject anchorGO = new GameObject("SpatialAnchor"); anchorGO.transform.SetParent(controllerAnchorPoint); anchorGO.transform.localPosition = Vector3.zero; anchorGO.transform.localRotation = Quaternion.identity; // 添加空间锚点组件 currentAnchor = anchorGO.AddComponent<OVRSpatialAnchor>(); // 等待锚点创建完成 yield return new WaitUntil(() => currentAnchor.Created); if (currentAnchor.Created) { // 获取锚点Transform并赋值 anchorobject = currentAnchor.gameObject; Debug.Log("空间锚点创建成功,Transform: " + currentAnchor.transform); } else { Debug.LogError("空间锚点创建失败"); Destroy(anchorGO); } } }
额外注意事项
- 确保Oculus Integration包版本与MRTK版本兼容,优先使用最新稳定版
- 在Unity Player Settings中开启Oculus空间感知权限
- 确认MRTK已配置正确的Oculus输入配置文件
内容的提问来源于stack exchange,提问作者Lin Martin
相关产品推荐
相关产品推荐

