Search Unity

Bug XRGeneralSettings.Instance is null in editor play mode. OpenVRLoader not initializing.

Discussion in 'XR Interaction Toolkit and Input' started by seowen1, Apr 16, 2021.

  1. seowen1

    seowen1

    Joined:
    Feb 22, 2018
    Posts:
    11
    Hi all,

    I've been experiencing an issue with Unity 2021.1 and the XR Plugin Management package. I'm also interfacing with the SteamVR plugin, but I don't think that is the problem.

    When I launch a play session in the editor with the correct settings for SteamVR and OpenVR with the Unity XR package, SteamVR returns an error of "Not Initialized" even though SteamVR is set to initialize on Awake, and Open VR Loader is checked and set to initialize on startup in under Project Settings > XR Plug-in Management.

    After some debugging, it seems that the XR component and the loader are simply not firing up on startup. The XRGeneralSettings.Instance == null, and therefore it does not initialize and interface with the SteamVR application. After a few play sessions it will randomly work and launch SteamVR and start interfacing correctly. At that point, XRGeneralSettings.Instance is assigned and working properly. It also seems to persist until I relaunch the editor, when I can then reproduce the issue. I believe this is because the Instance and loader are made to persist after they are created.

    I have managed to find a workaround, that has proven effective in my testing. The following code is within my own custom Player class that is the parent for a customized SteamVR Player.

    Code (CSharp):
    1. // XR/STEAMVR SYSTEM BROKEN
    2.         // XRGeneralSettings.Instance does not get auto-generated by default in editor.
    3.         // This workaraound involves manually creating Instance, Manager, and an OpenVRLoader.
    4.         // The Instance seems to persist between play sessions.
    5.         // Additional settings required:
    6.         // Edit > Project Settings > XR Plug-in Management > OpenVR Loader (Initialize XR on Startup = false)
    7.         // [SteamVR] component > Initialize Steam VR On Awake = false
    8.  
    9.         private IEnumerator StartXR() {
    10.             Debug.Log("Initializing XR...");
    11.  
    12.             if (XRGeneralSettings.Instance == null) {
    13.                 XRGeneralSettings.Instance = ScriptableObject.CreateInstance<XRGeneralSettings>();
    14.                 XRGeneralSettings.Instance.Manager = ScriptableObject.CreateInstance<XRManagerSettings>();
    15.                 var loader = ScriptableObject.CreateInstance<Unity.XR.OpenVR.OpenVRLoader>();
    16.                 XRGeneralSettings.Instance.Manager.TryAddLoader(loader);
    17.                 loader.Initialize();
    18.                 Debug.Log("OpenVRLoader created...");
    19.             }
    20.  
    21.             yield return XRGeneralSettings.Instance.Manager.InitializeLoader();
    22.  
    23.             if (XRGeneralSettings.Instance.Manager.activeLoader == null) {
    24.                 Debug.LogError("Initializing XR Failed. Check Editor or Player log for details.");
    25.             } else {
    26.                 Debug.Log("Starting XR...");
    27.                 XRGeneralSettings.Instance.Manager.StartSubsystems();
    28.                 SteamVR.Initialize(false);
    29.             }
    30.         }
    31.  
    32.         private void StopXR() {
    33.             Debug.Log("Stopping XR...");
    34.             if (XRGeneralSettings.Instance.Manager.isInitializationComplete) {
    35.                 XRGeneralSettings.Instance.Manager.StopSubsystems();
    36.                 XRGeneralSettings.Instance.Manager.DeinitializeLoader();
    37.             }
    38.             Debug.Log("XR stopped completely.");
    39.         }
    40.  
    41.         private void Start() {
    42.             StartCoroutine(StartXR());
    43.         }
    44.  
    45.         private void OnDestroy() {
    46.             StopXR();
    47.         }
    This has fixed the problem for me, but seems pretty clunky. I'm also not sure if this is only a problem in editor, but it seems to be.

    Any official response as to why this happens? Again, this seems related to the Unity.XR stuff, and not so much SteamVR. I would think the issue could be reproduced for other interfaces.

    Thanks!
     
  2. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    This should be set for you in `XRGeneralSettingsPerBuildTarget.PlayModeStateChanged`. I'd put a breakpoint in there and see if you are hitting that bp and if not, why?
     
  3. seowen1

    seowen1

    Joined:
    Feb 22, 2018
    Posts:
    11
    I am working with the compiled DLL for Unity.XR.Management.Editor so, I'm not sure how to put a breakpoint that would catch that...

    Can you provide an example of how I can catch this?
     
  4. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    If you set preference to generate all csproj files, you can generate a VS project that has the code for management in it (from Assets->Open C# Project). Open up the `XRGeneralSettingsPreBuildTarget.cs` file and put the bp in there, then attach VS to the Editor.

    This should also work with RIder and VS Code, just haven't tested it.
     
  5. seowen1

    seowen1

    Joined:
    Feb 22, 2018
    Posts:
    11
    Okay, I placed a bp and it never gets hit on entering playmode... It's like the event never fires off. I'm not sure why that would happen. Any other ideas?
     
  6. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    Above that section is where the hook is being set. Is that being called?
     
  7. seowen1

    seowen1

    Joined:
    Feb 22, 2018
    Posts:
    11
    It is not being called. It's weird, because after trying for a few minutes it will randomly get called appropriately, and then work after that. But if I restart Unity and attach the debugger and run it again it will not get called. I'm referring to the OnEnable() method within UNITY_EDITOR defines, under the XRGeneralSettingsPerBuildTarget class.

    Is it possible there's a race condition between when the OnEnable method where the event is subscribed to and the EditorApplication.playModeStateChanged event being called?
     
  8. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    It's possible, but XRGeneralSettingsPerBuildTarget is marked InitializeOnLoad, which should load and enable it immediately. It's possible you found a bug in 2021.1 as well in regards to SOs. Would you be willing to downgrade your project (or make a new one if it's simple) and see if it repros in 2020.3?

    Either way, once you know, can you file a bug and report the case id here?
     
  9. seowen1

    seowen1

    Joined:
    Feb 22, 2018
    Posts:
    11
    I can definitely do that once I'm sure there's not something else causing this. I did notice that the XRGeneralSettings.asset file has m_AutomaticLoading, m_AutomaticRunning set to false. Based on what I can tell, these should be set to true?
     
  10. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    They should be if you want it to start, but that shouldn't stop the Instance from being set, just XR from starting. Make sure that `Initialize XR on Startup` is toggle true and that should set those values.
     
  11. seowen1

    seowen1

    Joined:
    Feb 22, 2018
    Posts:
    11
    Ah understood. I didn't realize that's what tied those together... Okay well yea then that is unrelated. I've tried both. I will attempt to get a smaller project uploaded in the future to open a bug report. Thanks for your help.