从代码启用/禁用 VR

Posted

技术标签:

【中文标题】从代码启用/禁用 VR【英文标题】:Enable/Disable VR from code 【发布时间】:2016-04-18 19:00:28 【问题描述】:

对于部署到 android 设备的应用,如何在 Unity 中以编程方式将显示设置为立体?

我想要一个用户可以在“VR 模式”和普通模式之间切换的 UI 菜单。默认情况下我不想要 VR 模式,因为它应该是运行时的一个选项。我知道在构建设置中有一个“支持虚拟现实”的设置,但同样,我不希望默认启用它。

【问题讨论】:

【参考方案1】:

在顶部包含using UnityEngine.XR;

使用空字符串调用XRSettings.LoadDeviceByName(""),后跟XRSettings.enabled = false;,在启动函数中禁用VR以禁用VR。

如果您想稍后启用它,请致电 XRSettings.LoadDeviceByName("daydream"),并使用 VR 名称后跟 XRSettings.enabled = true;

您应该在每个函数调用之间等待一个帧。这需要使用协程函数来完成。

另外,在某些 VR 设备上,您必须转到 Edit->Project Settings->Player 并确保 Virtual Reality Supported 复选框被选中(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() 禁用它。如果您使用的不是 daydream,请将该 VR 设备的名称传递给 EnableVR() 函数中的 LoadDevice 函数。

【讨论】:

我试过了,但它没有做任何事情。这个 sn-p 是否有特定的地方可以启用它? 不。您使用的是哪个 Unity 版本? 这应该适用于该版本。根据 Unity,它在编辑器中不起作用。它将在独立版本中工作。试试看。 我尝试在 Awake() 中启用它,然后记录 UnityEngine.VR.VRSettings.enabled 的值,但它仍然是错误的。就像设置没有采取。 很长一段时间......你是对的,它就像 10 天,在软件年中是 5 年! :) 等一下,我明天会试试 4 确定 ........ 抱歉没有在这里看到你的消息......【参考方案2】:

对于较新的 Unity 版本(例如 2019.4.0f1),您可以使用 XR Plugin Management 包。

启用通话:

XRGeneralSettings.Instance.Manager.InitializeLoader();

禁用通话:

XRGeneralSettings.Instance.Manager.DeinitializeLoader();

【讨论】:

终于有正确答案了。这次真是万分感谢。这是文档:docs.unity3d.com/Packages/com.unity.xr.management@3.0/api/… 对于任何面临同样问题的人,您需要先包含这一行:使用 UnityEngine.XR.Management;【参考方案3】:

我使用的是 Unity 2021,但这可能适用于早期版本,我也在使用 XR 插件管理。

开始: XRGeneralSettings.Instance.Manager.StartSubsystems();

停止: XRGeneralSettings.Instance.Manager.StopSubsystems();

完整文档位于: https://docs.unity3d.com/Packages/com.unity.xr.management@4.0/manual/EndUser.html

【讨论】:

【参考方案4】:

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);
    

【讨论】:

【参考方案5】:
 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();
   

【讨论】:

以上是关于从代码启用/禁用 VR的主要内容,如果未能解决你的问题,请参考以下文章

启用和禁用代码功能的 C 宏

在 Bootstrap DatePicker 中启用/禁用日期范围

为啥“barrier()”足以禁用或启用抢占?

通过js启用/禁用aspx验证器在后面的代码中不成立?

当我在代码中设置属性时,情节提要选项是启用还是禁用是不是重要?

使用 Froyo 2.2 上的代码启用/禁用移动数据 (GPRS)