Unity XR Development

Fixing VR Scene Loading Issues After Closing an AR Session in Unity

The scene transition seemed straightforward: call SceneManager, load the VR environment, and carry on. Instead, I was met with a persistent black screen while audio played perfectly in the background.

Need supporting assets, scene references, or production files to test this Unity workflow beyond the article?

Open on 3DCGHub

1. The Symptom and Initial Suspicions

The issue was specific and maddeningly consistent. After leaving an AR-enabled scene to enter a pure VR scene, the application would report that the scene loaded, but the headset display remained completely black. Surprisingly, pulling the headset off and putting it back on would force the rendering to kick in.

My initial assumption was that the camera stack wasn't re-initializing correctly. I spent hours tweaking the Camera component settings, depth clearing, and checking my render pipeline assets, convinced it was an occlusion or initialization order issue.

  • Audio triggers confirmed the scene change was successful.
  • Headset proximity sensor toggle served as a temporary, broken workaround.
  • Individual scenes functioned perfectly when loaded in isolation.

2. Reproducing and Isolating the Fault

To rule out faulty logic in the new scene, I created a minimal reproduction. By isolating the transition, I confirmed that the VR scene itself wasn't the culprit; the issue was tied exclusively to the handover from the active AR session.

Since the headset sensor reset the display, I shifted my focus to the XR subsystem lifecycle. It became clear that the AR session was not properly yielding its hold on the hardware display pipeline.

  • Created a stripped-down transition test case.
  • Verified that the AR camera was still technically 'active' in the backend.
  • Ruled out standard SceneManager async operations.

3. Debugging the XR Session State

I started inspecting the OpenXR session state logs. Even though I was loading a new scene, the XR session was essentially 'stuck' in the previous spatial state, expecting an AR environment that no longer needed to be processed.

The breakthrough came when I realized I was bypassing the required explicit shutdown of the XR Loader. Without an explicit stop call, the subsystem was failing to flush its previous state during the scene unload.

  • Monitored XRLoader activity during the scene unload.
  • Checked subsystem connectivity states in the Profiler.
  • Confirmed that the hardware display was holding onto the AR buffer.

4. The Fix: Explicit Subsystem Management

The fix required a strict cleanup sequence. In the AR scene, I needed to call the session stop method before requesting the next scene load. Correspondingly, once the new VR scene was initialized, I needed to force an explicit start to re-acquire the display.

This ensures the subsystem releases the hardware resources correctly before the scene manager attempts to bind the new camera to the VR view.

  • Called XRGeneralSettings.Instance.Manager.StopSubsystems() before loading the new scene.
  • Invoked XRGeneralSettings.Instance.Manager.StartSubsystems() within the Start method of the VR scene.
  • Verified frame updates in the Frame Debugger after the transition.

FAQ

Is this fix required for all OpenXR devices?

While this is most common on the Meta Quest, explicitly managing your XR subsystems is best practice across all OpenXR devices to ensure clean state transitions.

Will this cause a flicker during the transition?

There may be a brief moment of tracking loss as the subsystems restart, but it is significantly more stable than the black-screen hang you are currently experiencing.