How to detect VR and enable VR

If I’m in PIE and chose to not do VR Preview, I’d like the game to not think VR is available.

I have this code snippet that checks for a vr headset enabled setting so the game can either be in VR or not VR mode:

    //Try detecting the VR headset
    if (bVrHeadsetEnabled && GEngine->XRSystem.IsValid())
    {
        GEngine->XRSystem->GetHMDDevice()->EnableHMD(true);
        bVrHeadsetEnabledNow = GEngine->XRSystem->GetHMDDevice()->IsHMDEnabled();
    }
    else
    {
        bVrHeadsetEnabledNow = false;
    }

If I do normal PIE, this code still ends up enabling my VR codepaths because the VR headset is available. I’m then stuck with a normal PIE window without VR itself working but my character is controlled by VR.

I also remember earlier engine versions had a console command called stereo enable to toggle normal windowed mode versus being in VR.

How do we do something similar now? Also is there a good way to have a VR window and a non-VR destkop window at the same time like many games do?

I also noticed the OpenXR implementation of XRSystem always returns true and never actually does anything when EnableHMD is called?

Seems like the IStereoRendering::IsStereoEnabled() and IStereoRendering::EnableStereo() functions should work for it, along with the vr.bEnableStereo console command.

The desktop window is called a spectator screen, and you can control what to show in it through ISpectatorScreenController.

1 Like

Oh thanks! I’ll look at those more soon.

I’m now working on adding these checks to my game. I’m wondering is it ever possible to run in stereo mode while there are multiple local players? I’m building my code as if there is a window with split screen, and one of the players has VR enabled while others do not. However I’m not sure how to truly enable that support. It seems like the spectator screen is built for showing what the VR view sees not for rendering alternative views.

I’ve seen games I know are built in Unity, such as Keep Talking and Nobody Explodes, and also Beatsaber has the editor mode, that seem to run a separate window. I have yet to experiment more with this.

The spectator screen has a mode for passing an arbitrary texture to it. The VR template has an example of rendering a different viewpoint to it using a scene capture component.

1 Like

I also wrote this bit of code for detecting VR Preview mode in editor.

#if WITH_EDITOR
#include "Editor/EditorEngine.h"
#endif


#if WITH_EDITOR
	if (GIsEditor)
	{
		if (UEditorEngine* EdEngine = Cast<UEditorEngine>(GEngine))
		{
			if (EdEngine->IsVRPreviewActive())
			{
				UE_LOG(RDVR, Log, TEXT("URDVRLocalPlayerState::RefreshGlobalVR Forcing VR enabled for player 0 for Editor VR Preview Mode"));
				VrLocalPlayerIndexSetting = 0;
				bIsVREnabledSetting = true;
			}
			else if (EdEngine->IsPlayingSessionInEditor())
			{
				UE_LOG(RDVR, Log, TEXT("URDVRLocalPlayerState::RefreshGlobalVR Forcing VR disabled because running Editor non VR Preview Mode"));
				bIsVREnabledSetting = false;
			}
		}
	}
#endif

And add this to your module build rules.

        if (Target.bBuildEditor)
        {
            PrivateDependencyModuleNames.AddRange(
                new string[]
                {
                    "UnrealEd"
                }
            );
        }

This code truly detects if you ran with VR Preview mode and should be used in place of the other code here. VR Preview mode is a bit special it seems, and setting stereo on/off and detecting HMD status doesn’t matter as much.

1 Like