Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

toggle between 2d and Google Cardboard

Discussion in 'AR/VR (XR) Discussion' started by lz7cjc, May 31, 2020.

  1. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    Hi
    I have just upgraded to the new XR Plug-In system and don't understand how to toggle between 2d and VR screens.
    This is how I used to do it:
    Code (CSharp):
    1.  
    2.         XRSettings.LoadDeviceByName(YesVR);
    3.  
    4.         yield return null;
    5.  
    6.         XRSettings.enabled = true;
    how do i do the same with the new system?
    thanks
     
  2. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    684
    Relevant docs: https://docs.unity3d.com/Packages/com.unity.xr.management@3.2/manual/EndUser.html

    You need to take manual control by disabling the Initialize at start option. Then you need to manage make sure you manually call the management lifecycle methods to Init and Start subsystems to enter VR, then Stop and De-init subsystems to leave VR.

    Special not that InitializeAsync is meant to be called from within a co-routine.
     
    a436t4ataf likes this.
  3. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    so i managed to uncheck the box but it went rapidly downhill from there. The documentation makes zero sense to me. Any chance you can explain? I guess it is easy if you know the answer but i have no clue.

    What code do i need to turn on/off? Given it was only a few lines in the old system it would be very helpful if you could let us know what to replace with

    thanks
     
  4. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    684
    I tested this with Mock device so I know it works (don't have another device to test with just right now). However, it's totally provider agnostic and should give you an idea of how this works in general:

    Here's the setup in settings:
    upload_2020-6-2_8-59-25.png

    And here is the code I used to test:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. using UnityEditor.XR.Management;
    6. using UnityEngine.XR.Management;
    7.  
    8. public class ManualXRControl : MonoBehaviour
    9. {
    10.     [Tooltip("Wait time in seconds before we start and stop XR.")]
    11.     public float waitTime = 10.0f;
    12.  
    13.     void Start()
    14.     {
    15.         StartCoroutine(StartXR());
    16.     }
    17.  
    18.     IEnumerator StartXR()
    19.     {
    20.         Debug.Log($"Waiting {waitTime}s till we start XR...");
    21.         yield return new WaitForSecondsRealtime(waitTime);
    22.  
    23.         Debug.Log("Initializing XR...");
    24.         yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
    25.  
    26.  
    27.         if (XRGeneralSettings.Instance.Manager.activeLoader == null)
    28.         {
    29.             Debug.LogError("Initializing XR Failed. Check Editor or Player log for details.");
    30.         }
    31.         else
    32.         {
    33.             Debug.Log("Starting XR...");
    34.             XRGeneralSettings.Instance.Manager.activeLoader.Start();
    35.  
    36.             Debug.Log($"Waiting {waitTime}s to stop XR...");
    37.             yield return new WaitForSecondsRealtime(waitTime);
    38.  
    39.             StopXR();
    40.         }
    41.     }
    42.  
    43.     void StopXR()
    44.     {
    45.         Debug.Log("Stopping XR...");
    46.  
    47.         if (XRGeneralSettings.Instance.Manager.activeLoader != null)
    48.         {
    49.             XRGeneralSettings.Instance.Manager.activeLoader.Stop();
    50.             XRGeneralSettings.Instance.Manager.activeLoader.Deinitialize();
    51.             Debug.Log("XR stopped completely.");
    52.         }
    53.     }
    54. }
    55.  
     
    a436t4ataf and lz7cjc like this.
  5. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    that is way above my paygrade! thanks so much. I will have a play around and see how badly I can break it!
    thanks v much for your help
     
  6. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    first problem when trying to build, after creating the script and pasting your code into it:
    error CS0234: The type or namespace name 'Management' does not exist in the namespace 'UnityEditor.XR' (are you missing an assembly reference?)
    any help appreciated!
    thanks
     

    Attached Files:

  7. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    684
    That would imply that the management plugin is not there, but the image shows it is. Are there any other errors in the console that could be halting the compilation process as well?
     
  8. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    I get this error when I try to run the script
    Initializing XR Failed. Check Editor or Player log for details.
    UnityEngine.Debug:LogError(Object)
    <StartXR>d__2:MoveNext() (at Assets/MyStuff/Scripts/using/ManualXRControl.cs:29)
    UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

    My understanding of your code is it bounces between turning the VR function on and off after the delay of 10s. Is that correct? So If I want to switch off for a scene, I call StopXR() and if I want to start it then I use StartXR(), removing the call to the StopXR() function
     
  9. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    there are no other errors on the console
     
  10. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    these are the plugins that I have installed
     

    Attached Files:

  11. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    684
    That is correct. You are running this on device or in editor? If in editor, it won't work if there are no standalone devices selected. If on device, then there is an issue with the Cardboard plugin you may be running into.

    I'm not sure what the Cardboard plugin is doing, or what Google is providing as we don't handle that directly. You may also need to loop in their support for this as well.
     
  12. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    I am trying to build it so I can test with my headset but the apk fails to build. That is my problem. I get the error above about namespace "management"
     
  13. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    684
    If you switch to Standalone, add the Mock HMD device and build it out does it work then? Just trying to isolate this to an Android build issue or not.
     
  14. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    i unchecked google cardboard then switched to PC, Linux Standalone - is that what you meant by standalone?
    I still get the errors:
    Library\PackageCache\com.google.xr.cardboard@8979e065b7\Runtime\Api.cs(164,33): error CS0117: 'ApiConstants' does not contain a definition for 'CardboardXRUnity'
    Looks like i have missed turning off cardboard somewhere
     

    Attached Files:

  15. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    684
    Can you post a small sample project I can look at?
     
  16. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    I can try - what do i need to do? upload a scene and script here?
     
  17. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    684
    Just zip up your project folder (remove everything but Assets, Packages, and Project Settings from the zip) and then you can upload it here using "Upload file".
     
  18. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    684
    And remove anything that is private or sensitive.
     
  19. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    684
    Remove ```using UnityEditor.XR.Management``` from that script.

    Sorry about that.
     
  20. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    sounds promising :)) will give it a go
     
  21. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    gettting there!
    I have built the apk successfully and it now loads in 2d

    however when I try to flip to VR it doesn't work

    These are my two scripts:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.XR.Management;
    5.  
    6. public class VRToggle : MonoBehaviour
    7. {
    8.  
    9.     void Start()
    10.     {
    11.         StartCoroutine(StartXR());
    12.     }
    13.  
    14.     IEnumerator StartXR()
    15.     {
    16.  
    17.         yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
    18.         XRGeneralSettings.Instance.Manager.activeLoader.Start();
    19.         XRGeneralSettings.Instance.Manager.activeLoader.Deinitialize();
    20.     }
    21. }
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.XR.Management;
    5.  
    6. public class VRToggleNo : MonoBehaviour
    7. {
    8.  
    9.     void Start()
    10.     {
    11.         StartCoroutine(NoVR());
    12.     }
    13.  
    14.     IEnumerator NoVR()
    15.     {
    16.         yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
    17.         XRGeneralSettings.Instance.Manager.activeLoader.Stop();
    18.         XRGeneralSettings.Instance.Manager.activeLoader.Deinitialize();
    19.     }
    20. }
    21.  
     
  22. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    I get these errors when I run in Editor
    ArgumentNullException: Value cannot be null.
    Parameter name: _unity_self
    UnityEngine.XR.Management.XRLoaderHelper.StartSubsystem[T] () (at Library/PackageCache/com.unity.xr.management@3.2.10/Runtime/XRLoaderHelper.cs:55)
    Unity.XR.MockHMD.MockHMDLoader.Start () (at Library/PackageCache/com.unity.xr.mock-hmd@1.0.1-preview.7/Runtime/MockHMDLoader.cs:35)
    VRToggle+<StartXR>d__3.MoveNext () (at Assets/MyStuff/Scripts/using/VRToggle.cs:28)
    UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <e98ed0368295432e8c11e52d6243ee11>:0)


    mockhmd is turned off as i can't control the scene with this turned on
     
  23. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    anyone finding yourself here, this is the working code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.XR.Management;
    5.  
    6. public class VRToggle : MonoBehaviour
    7. {
    8.     public bool m_active;
    9.  
    10.     private void Update()
    11.     {
    12.      
    13.                 if (!m_active)
    14.                 {
    15.                  
    16.                     StopXR();
    17.                 }
    18.                 else
    19.                 {
    20.                    
    21.                     StartXR();
    22.                 }
    23.             }
    24.     //    }
    25.     //}
    26.  
    27.     public void StartXR()
    28.     {
    29.    
    30.         XRGeneralSettings.Instance.Manager.InitializeLoaderSync();
    31.         XRGeneralSettings.Instance.Manager.StartSubsystems();
    32.     }
    33.  
    34.     public void StopXR()
    35.     {
    36.      
    37.         if (XRGeneralSettings.Instance.Manager.isInitializationComplete)
    38.         {
    39.             XRGeneralSettings.Instance.Manager.StopSubsystems();
    40.         }
    41.     }
    42. }
    thank you @joejo for all your help
     
  24. lodendsg

    lodendsg

    Joined:
    Sep 1, 2012
    Posts:
    196
    Your code worked to start XR however when stoping it did not return rendering to the '2D' display anyone else run into this or have a hint as to what I might be doing wrong.

    I actually got it to partially work by calling XRGeneralSettings.Instance.Manager.activeLoader.Deinitialize(); after StopSubsystems the issue though is that the camera is all out of wack and changing values on the camera or via Cinamchine isn't having any effect ... its as if the display gets stuck at whatever the last state was for the headset and nothing trying to make updates else where will have any effect.

    Second Edit
    So calling XRGeneralSettings.Instance.Manager.activeLoader.Deinitialize(); does return rendering to standard output (monitor) but it also makes it so I cant restart XR that is if I try and call StartXR after StopXR I get errors and no rendering.

    Would be great if Unity could give us a clear and managable way to enable/disable XR Rendering without having to monkey around so much. I'm also noticing in the new system that only 1 eye gets sky box and now for some reason only 1 eye gets any rendering ... I assume thats just a setting I jacked up someone while poking around with how the hell to simply enable disable XR rendering at run time.

     
    Last edited: Jun 8, 2020
  25. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    here is my final code which seems to work fine:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.XR.Management;
    5.  
    6. public class VRToggle : MonoBehaviour
    7. {
    8.     public bool m_active;
    9.  
    10.     private void Update()
    11.     {
    12.      
    13.                 if (!m_active)
    14.                 {
    15.                  
    16.                     StopXR();
    17.                 }
    18.                 else
    19.                 {
    20.                    
    21.                     StartXR();
    22.                 }
    23.             }
    24.     //    }
    25.     //}
    26.  
    27.     public void StartXR()
    28.     {
    29.    
    30.         XRGeneralSettings.Instance.Manager.InitializeLoaderSync();
    31.         XRGeneralSettings.Instance.Manager.StartSubsystems();
    32.     }
    33.  
    34.     public void StopXR()
    35.     {
    36.      
    37.         if (XRGeneralSettings.Instance.Manager.isInitializationComplete)
    38.         {
    39.             XRGeneralSettings.Instance.Manager.StopSubsystems();
    40.         }
    41.     }
    42. }
    hope that helps
     
  26. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    684
    Note that sync can be expensive and time consuming. You should try to use the default async call instead unless you are sure you are OK with the cost.
     
  27. lodendsg

    lodendsg

    Joined:
    Sep 1, 2012
    Posts:
    196
    Thanks .. ya I think its working ... the issues I was seeing appear to be due to multiple camera layers that is we have a Base camera and a couple overlay cameras and XR doesn't seem to like that ... that or it has some caviots

    I'll dig around and see what info I can find on that aspect.

    Edit ...
    Its not working
    while I can start in a non-XR mode and switch to XR switching back just frezzes the display, if I then switch back int XR for a second time display resumes. So it would seem that the standard monitor display is not being returned to correctly

    Edit 2 ...
    So with a single camera set up XRGeneralSettings.Instance.Manager.DeinitializeLoader(); does work ... and is required to get non-XR display to work correctly. It does work when I restart. So I think the only issue I have at the moment is the inability to use an overlay camera.
     
    Last edited: Jun 9, 2020
  28. XargonInSpace

    XargonInSpace

    Joined:
    Nov 5, 2018
    Posts:
    4
    When you go to reinitialize - does the application crash on android?
     
  29. DarkVerse

    DarkVerse

    Joined:
    Jan 9, 2017
    Posts:
    46
    Surely this will be attempting to start the XR system on every frame once m_active is set true. Do those methods have no effect if the system is already started? Is there a way to check if the XR system is started and a valid subsystem is loaded and active?
     
    Last edited: Jun 15, 2020
  30. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    i didn't say it was a good answer, just one that worked! hoping someone with more than a few months of unity will step up and give a best practice answer but there was no such gold standard when i did this!
     
    DarkVerse likes this.
  31. lodendsg

    lodendsg

    Joined:
    Sep 1, 2012
    Posts:
    196
    Doesn't 'crash' just doesn't render correctly when I have overlay cameras ... its all quite a mess so for the time being we have steped back to what we think is the simpler set up of PC only, XR + Desktop presentaiton 1 camera no overlay using URP ... still a pain in the backside to do simple things but getting there
     
  32. DarkVerse

    DarkVerse

    Joined:
    Jan 9, 2017
    Posts:
    46
    I am starting to looking into this now, porting a previous VR app into the new XR system and one requirement is to switch between VR mode and magic window mode, ie mono screen but tracked. I will post here if I find anything useful.
     
  33. XargonInSpace

    XargonInSpace

    Joined:
    Nov 5, 2018
    Posts:
    4
    Just to clarify with your implementation of the Carboard XR Plugin, while testing on an android device your application does not crash if you follow this sequence? Stop() > DeinitializeLoader() > InitializeLoader() > Start()

    If so, could I see your code/sequence please?
     
  34. iwellsSI

    iwellsSI

    Joined:
    Jan 14, 2014
    Posts:
    6
    Thanks for the help on this forum, it took some finding but it's helped a lot. My problem now is that on iOS it works great, but on Android it works once then when I leave the VRscene to go to a non-VR scene and go back into the VR scene the app crashes and I'm given a "Null Pointer Dereference" error. It fails in the same point when it is trying to initialize loader sync (XRGeneralSettings.Instance.Manager.InitializeLoaderSync();). Below is the code I've used and by using the Unity Android Logcat plugin have been able to copy the crash log into a .txt file. It always crashes after Debug.Log("3") on entering the VR scene a second time.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.XR.Management;
    5.  
    6. public class ToggleVRController : MonoBehaviour
    7. {
    8.     public bool _startInVR;
    9.     public bool _setInPortrait;
    10.  
    11.     // Start is called before the first frame update
    12.     void Start()
    13.     {
    14.         if(_startInVR)
    15.         {
    16.             Debug.Log("Starting VR");
    17.             StartCoroutine(StartInVR());
    18.  
    19.             Debug.Log("Finished Starting VR");
    20.         }
    21.         else
    22.         {
    23.             StopVR();
    24.            
    25.             if (_setInPortrait)
    26.             {              
    27.                 Screen.autorotateToPortrait = true;
    28.                 Screen.autorotateToPortraitUpsideDown = false;
    29.                 Screen.autorotateToLandscapeLeft = false;
    30.                 Screen.autorotateToLandscapeRight = false;
    31.             }
    32.            
    33.         }
    34.     }
    35.  
    36.    
    37.     IEnumerator StartInVR()
    38.     {
    39.         Debug.Log("1");
    40.         Screen.orientation = ScreenOrientation.LandscapeLeft;   // This is placed here because if it was in another script the app would crash.
    41.  
    42.         Debug.Log("2");
    43.         yield return new WaitForSeconds(0.2f);
    44.  
    45.         Debug.Log("3");
    46.         XRGeneralSettings.Instance.Manager.InitializeLoaderSync();
    47.         Debug.Log("4");
    48.         XRGeneralSettings.Instance.Manager.StartSubsystems();
    49.  
    50.         Debug.Log("Finished Loading VR");
    51.     }
    52.    
    53.    
    54.     public void StopVR()
    55.     {
    56.         if(XRGeneralSettings.Instance.Manager.isInitializationComplete)
    57.         {
    58.             XRGeneralSettings.Instance.Manager.StopSubsystems();
    59.             XRGeneralSettings.Instance.Manager.DeinitializeLoader();
    60.  
    61.             Debug.Log("STOPPED VR");
    62.         }
    63.     }
    64. }
    65.  
     

    Attached Files:

  35. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    152
    can't help on that but given you are using Mac can you help me understand how i control my scene when in game mode? I have asked a couple of questions on here but not got a response

    https://forum.unity.com/threads/how-do-i-control-scene-in-editor-with-new-xr-plugin-manager.917423/

    The problem seems to be that i have to remove the old GoogleVR tools to build the app and i can't find anything to replace GvrEditorEmulator (sorry for off topic but am desperate so i can debug my iphone version.!)
     
  36. iwellsSI

    iwellsSI

    Joined:
    Jan 14, 2014
    Posts:
    6
    In short, to answer your question I used the Unity tutorial about Interactive 360 and placed the Camera Editor Control script onto a empty game object that is a parent to the main camera.
     
  37. iwellsSI

    iwellsSI

    Joined:
    Jan 14, 2014
    Posts:
    6
    Hi, I am still having trouble with the app suffering a critical failure and crashing the app the second time I run VR on Android. I'll include the tombstone file. Can anyone help, please?
     

    Attached Files:

unityunity