Sofia Clover
Sofia Clover

Reputation: 679

Enable/Disable VR from code

How can I set the display to stereoscopic programmatically in Unity for an app deployed to an Android device?

I want a UI menu where the user can toggle between "VR mode" and normal mode. I do not want VR mode by default as it should be an option at run-time. I know there is a setting for "Virtual Reality Supported" in the build settings, but again, I do not want this enabled by default.

Upvotes: 9

Views: 17825

Answers (5)

Sean Bannister
Sean Bannister

Reputation: 3185

I'm using Unity 2021 but this probably works in earlier versions, I'm also using XR Plug-in Management.

Start: XRGeneralSettings.Instance.Manager.StartSubsystems();

Stop: XRGeneralSettings.Instance.Manager.StopSubsystems();

Full documentation at: https://docs.unity3d.com/Packages/[email protected]/manual/EndUser.html

Upvotes: 2

Mandark
Mandark

Reputation: 828

2020.3.14f1

Doesn't work for me, I get this error when running my Android app.

Call to DeinitializeLoader without an initialized manager.Please make sure wait for initialization to complete before calling this API.

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

More context. I try to unload the Oculus loader, before he manages to load the plugin. I have an Android app, and the Oculus loader calls Application.Quit because the device is not an Oculus headset. Waiting for XRGeneralSettings.Instance.Manager.isInitializationComplete takes too long. Tried all RuntimeInitializeLoadType annotations.

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

SOLUTION

Made my build class extend IPreprocessBuildWithReport

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

///https://docs.unity3d.com/Packages/[email protected]/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);
    }
}

Upvotes: 1

Codemaker2015
Codemaker2015

Reputation: 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();
   }

Upvotes: -1

rusty
rusty

Reputation: 475

For newer builds of Unity (e.g. 2019.4.0f1) you can use the XR Plugin Management package.

To enable call:

XRGeneralSettings.Instance.Manager.InitializeLoader();

To disable call:

XRGeneralSettings.Instance.Manager.DeinitializeLoader();

Upvotes: 7

Programmer
Programmer

Reputation: 125275

Include using UnityEngine.XR; at the top.

Call XRSettings.LoadDeviceByName("") with empty string followed by XRSettings.enabled = false; to disable VR in the start function to disable VR.

When you want to enable it later on, call XRSettings.LoadDeviceByName("daydream") with the VR name followed by XRSettings.enabled = true;.

You should wait for a frame between each function call. That requires this to be done a corutine function.

Also, On some VR devices, you must go to Edit->Project Settings->Player and make sure that Virtual Reality Supported check-box is checked(true) before this will work. Then you can disable it in the Start function and enable it whenever you want.

EDIT:

This is known to work on some VR devices and not all VR devices. Although, it should work on Daydream VR. Complete code sample:

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

Call EnableVR() to enable vr and DisableVR() to disable it. If you are using anything other than daydream, pass the name of that VR device to the LoadDevice function in the EnableVR() function.

Upvotes: 13

Related Questions