从代码中启用/禁用虚拟现实

9

如何在Unity中以编程方式为部署到Android设备的应用程序设置立体声显示?

我想要一个用户可以在“VR模式”和正常模式之间切换的UI菜单。我不希望默认使用VR模式,因为它应该是运行时的选项。我知道在构建设置中有一个“支持虚拟现实”的设置,但是再次强调,我不想默认启用此功能。

5个回答

13

在顶部加上using UnityEngine.XR;

在启动函数中使用空字符串调用XRSettings.LoadDeviceByName(""),然后再接着使用XRSettings.enabled = false;来禁用VR以关闭VR。

如果您想稍后启用它,请调用 VR 名称并在其后跟 XRSettings.LoadDeviceByName("daydream"),然后再接着使用XRSettings.enabled = true;

在每个函数调用之间应该等待一个帧。这需要使用coroutine功能完成。

此外,在某些 VR 设备上,您必须进入编辑器->项目设置->玩家,确保支持虚拟现实选框为已选中(true),然后才能使此功能正常工作。然后可以在启动函数中禁用它,并在需要时启用它。

编辑

这在某些 VR 设备上可行,但不是所有 VR 设备都适用。尽管如此,它应该可以在 Daydream VR 上工作。完整代码示例:

IEnumerator LoadDevice(string newDevice, bool enable)
{
    XRSettings.LoadDeviceByName(newDevice);
    yield return null;
    XRSettings.enabled = enable;
}

void EnableVR()
{
    StartCoroutine(LoadDevice("daydream", true));
}

void DisableVR()
{
    StartCoroutine(LoadDevice("", false));
}

调用EnableVR()来启用VR,调用DisableVR()来禁用VR。如果您使用的是Daydream之外的任何其他VR设备,请将该VR设备的名称传递给EnableVR()函数中的LoadDevice函数。


不是的。你使用的Unity版本是什么? - Programmer
这应该适用于那个版本。根据Unity的说法,它在编辑器中不起作用,但在独立构建中可以正常工作。试一下吧。 - Programmer
我尝试在Awake()中启用它,然后记录了UnityEngine.VR.VRSettings.enabled的值,但它仍然是false。就像设置没有生效一样。 - Sofia Clover
编辑了我的答案,请查看修改内容。同时请勿在编辑器中尝试此操作,应该在构建时进行尝试才能生效。当前我正在打字测试此方法。 - Programmer
1
很久没联系了...你说得对,这已经是10天了,这在软件界就相当于5年!!:) 等一下,我明天一定会试试看......抱歉没看到你的信息在这里... - Fattie
显示剩余6条评论

7

对于较新版本的Unity(例如2019.4.0f1),您可以使用XR插件管理软件包。

要启用,请调用:

XRGeneralSettings.Instance.Manager.InitializeLoader();

禁用呼叫:

XRGeneralSettings.Instance.Manager.DeinitializeLoader();

终于得到正确的答案了。谢谢你。这是文档链接:https://docs.unity3d.com/Packages/com.unity.xr.management@3.0/api/UnityEngine.XR.Management.XRGeneralSettings.html - Captain GouLash
对于任何遇到相同问题的人,你需要首先包含这行代码:using UnityEngine.XR.Management; - Captain GouLash

2

0

2020.3.14f1

对我来说不起作用,当我运行我的Android应用程序时,我会收到这个错误。

在没有初始化管理器的情况下调用DeinitializeLoader。请确保在调用此API之前等待初始化完成。

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
        static void TryToDeinitializeOculusLoader()
        {
            XRGeneralSettings.Instance.Manager.DeinitializeLoader();
        }

更多上下文。 我试图在Oculus加载插件之前卸载它。 我有一个Android应用程序,而Oculus加载器调用Application.Quit,因为设备不是Oculus头戴式显示器。 等待XRGeneralSettings.Instance.Manager.isInitializationComplete太长时间了。 尝试了所有的RuntimeInitializeLoadType注释。

OculusLoader.cs

    #elif (UNITY_ANDROID && !UNITY_EDITOR)
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
        static void RuntimeLoadOVRPlugin()
        {
            var supported = IsDeviceSupported();

            if (supported == DeviceSupportedResult.ExitApplication)
            {
                Debug.LogError("\n\nExiting application:\n\nThis .apk was built with the Oculus XR Plugin loader enabled, but is attempting to run on a non-Oculus device.\nTo build for general Android devices, please disable the Oculus XR Plugin before building the Android player.\n\n\n");
                Application.Quit();
            }

            if (supported != DeviceSupportedResult.Supported)
                return;

            try
            {
                if (!NativeMethods.LoadOVRPlugin(""))
                    Debug.LogError("Failed to load libOVRPlugin.so");
            }
            catch
            {
                // handle Android standalone build with Oculus XR Plugin installed but disabled in loader list.
            }

        }
#endif

解决方案

让我的构建类扩展IPreprocessBuildWithReport接口

public void OnPreprocessBuild(BuildReport report)
{
    DisableXRLoaders(report);
}

///https://docs.unity3d.com/Packages/com.unity.xr.management@3.2/manual/EndUser.html
/// Do this as a setup step before you start a build, because the first thing that XR Plug-in Manager does at build time
/// is to serialize the loader list to the build target.

void DisableXRLoaders(BuildReport report)
{
    
    XRGeneralSettingsPerBuildTarget buildTargetSettings;
    EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
    if (buildTargetSettings == null)
    {
        return;
    }
    
    XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(report.summary.platformGroup);
    if (settings == null)
    {
        return;
    }
    
    XRManagerSettings loaderManager = settings.AssignedSettings;
    
    if (loaderManager == null)
    {
        return;
    }
    
    var loaders = loaderManager.activeLoaders;
    
    // If there are no loaders present in the current manager instance, then the settings will not be included in the current build.
    if (loaders.Count == 0)
    {
        return;
    }

    var loadersForRemoval = new List<XRLoader>();
    
    loadersForRemoval.AddRange(loaders);
    
    foreach (var loader in loadersForRemoval)
    {
        loaderManager.TryRemoveLoader(loader);
    }
}

-1
 public void Awake() {
          StartCoroutine(SwitchToVR(()=>{
                Debug.Log("Switched to VR Mode");
          }));

          //For disable VR Mode
          XRSettings.enabled = false;
  }
 
  IEnumerator SwitchToVR(Action callback) {
            // Device names are lowercase, as returned by `XRSettings.supportedDevices`.
            // Google original, makes you specify
            // string desiredDevice = "daydream"; // Or "cardboard".
            // XRSettings.LoadDeviceByName(desiredDevice);
            // this is slightly better;
            
            string[] Devices = new string[] { "daydream", "cardboard" };
             XRSettings.LoadDeviceByName(Devices);
      
            // Must wait one frame after calling `XRSettings.LoadDeviceByName()`.
            yield return null;
          
            // Now it's ok to enable VR mode.
            XRSettings.enabled = true;
            callback.Invoke();
   }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接