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

Unity VR构建切换场景后Meta Quest 2控制器失效问题求助

问题描述与修复方案

1.0 应用目标

允许用户上传3D模型,通过UI Canvas按钮实时调整(缩放、纹理),再将该模型带入其他场景(如厨房环境)进行进一步调整或移动。

2.0 技术栈

Unity XR Interaction Toolkit、Unity3D、C#、MacOS

3.0 问题

点击切换场景按钮后,新场景成功加载且3D模型保留,但Meta Quest 2控制器在新场景中完全失效,无法进行移动操作。

4.0 排查过程

  • 初始阶段控制台持续输出You have two event systems警告,无报错信息。移除场景2的Event System后,控制器恢复正常,但场景2的UI Canvas按钮失效,推测是前场景未正确卸载导致双Event System冲突。
  • 使用SceneManager.UnloadScene()后警告消失,但VR控制器仍失效,编辑器内测试一切正常。尝试SceneManager.UnloadSceneAsync()、先禁用再启用场景2的Event System等操作均无效果。
  • 初步定位问题出在跨场景迁移模型的SwitchScene脚本,推测XR Interaction Toolkit的核心组件未完成正确迁移——比如用户上传模型的XR Grab Interactable组件在新场景中丢失了对XR Interaction Manager GameObject的引用。

5.0 现有SwitchScene脚本

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManager;

public class SwitchScene : MonoBehaviour
{
    // 在Inspector中指定要加载的场景名称
    public string sceneName;

    // 要迁移到下一场景的GameObject
    private GameObject userModel;

    public void OnClick()
    {
        // 查找用户上传的模型(父GameObject名为"1")
        userModel = GameObject.Find("1");
        StartCoroutine(LoadYourAsyncScene());
    }

    IEnumerator LoadYourAsyncScene()
    {
        // 记录当前场景,用于后续卸载
        Scene currentScene = SceneManager.GetActiveScene();

        // 异步加载目标场景(加载模式为Additive)
        AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);

        // 等待场景加载完成
        while (!asyncLoad.isDone)
        {
            yield return null;
        }

        // 将模型移动到新加载的场景
        SceneManager.MoveGameObjectToScene(userModel, SceneManager.GetSceneByName(sceneName));

        // 卸载当前场景
        SceneManager.UnloadScene(currentScene);
    }
}

修复方案

针对控制器失效和XR组件引用丢失的问题,给出以下修复步骤:

1. 统一XR核心组件的持久化管理

将XR Interaction Manager、XR Origin等XR核心组件放在一个永不卸载的持久化场景(比如XRSetup场景)中,项目启动时优先加载该场景,后续业务场景均以Additive模式加载,避免场景切换时销毁或丢失这些核心依赖组件。

2. 修正场景切换逻辑,设置新场景为激活状态

当前脚本卸载旧场景后未指定新场景为激活场景,导致XR输入系统无法正确绑定。修改LoadYourAsyncScene协程:

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManager;

public class SwitchScene : MonoBehaviour
{
    public string sceneName;
    private GameObject userModel;

    public void OnClick()
    {
        userModel = GameObject.Find("1");
        StartCoroutine(LoadYourAsyncScene());
    }

    IEnumerator LoadYourAsyncScene()
    {
        Scene currentScene = SceneManager.GetActiveScene();
        AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
        asyncLoad.allowSceneActivation = true;

        while (!asyncLoad.isDone)
        {
            yield return null;
        }

        Scene targetScene = SceneManager.GetSceneByName(sceneName);
        // 将模型迁移到新场景
        SceneManager.MoveGameObjectToScene(userModel, targetScene);
        // 设置新场景为激活场景
        SceneManager.SetActiveScene(targetScene);
        // 异步卸载旧场景,避免阻塞主线程
        yield return SceneManager.UnloadSceneAsync(currentScene);
    }
}

3. 修复XR Grab Interactable的引用丢失问题

在模型迁移到新场景后,手动重新绑定XR Grab Interactable的交互管理器引用:

// 在MoveGameObjectToScene之后添加以下代码
XRGrabInteractable grabInteractable = userModel.GetComponentInChildren<XRGrabInteractable>();
if (grabInteractable != null)
{
    grabInteractable.interactionManager = FindObjectOfType<XRInteractionManager>();
}

注意需要引入using UnityEngine.XR.Interaction.Toolkit;命名空间。

4. 处理Event System冲突

保留每个场景的Event System,在场景切换时自动禁用旧场景的Event System,启用新场景的:

// 在SetActiveScene之后添加以下代码
using UnityEngine.EventSystems;
using System.Linq;

// 禁用旧场景的Event System
EventSystem oldEventSystem = currentScene.GetRootGameObjects()
    .Select(go => go.GetComponent<EventSystem>())
    .FirstOrDefault(es => es != null);
if (oldEventSystem != null)
{
    oldEventSystem.enabled = false;
}

// 启用新场景的Event System
EventSystem newEventSystem = targetScene.GetRootGameObjects()
    .Select(go => go.GetComponent<EventSystem>())
    .FirstOrDefault(es => es != null);
if (newEventSystem != null)
{
    newEventSystem.enabled = true;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:35:34