SteamVR
SteamVR
#Overview
name: SteamVR
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
It is referenced in 11
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of SteamVR in Unreal Engine 5 is to provide support for the SteamVR platform, enabling developers to create virtual reality experiences compatible with SteamVR-supported devices.
SteamVR is primarily used in the VR Editor subsystem and the OpenXR plugin. It affects various aspects of VR interaction, including input handling, UI placement, and rendering.
The value of this variable is typically set based on the detected HMD device type. It’s not a single variable but rather a platform identifier used in various parts of the engine.
SteamVR interacts with other variables and systems related to VR, such as OculusHMD and general VR input systems.
Developers should be aware that:
- SteamVR has specific input handling methods, particularly for trackpad interactions.
- UI element positioning and behavior may differ between SteamVR and other VR platforms.
- There are platform-specific optimizations and workarounds, such as for rendering and frame synchronization.
Best practices when using SteamVR include:
- Always check the HMD device type before applying SteamVR-specific logic.
- Consider the differences in input methods and UI placement when designing VR interactions.
- Be aware of platform-specific rendering and performance considerations.
- Test thoroughly on SteamVR devices to ensure compatibility and optimal performance.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEngine.ini:3222, section: [HMDPluginPriority]
- INI Section:
HMDPluginPriority
- Raw value:
30
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Plugins/Runtime/OpenXR/Source/OpenXRHMD/Private/OpenXRHMD.cpp:3419
Scope (from outer to inner):
file
function void FOpenXRHMD::OnBeginRendering_RHIThread
Source code excerpt:
// We do not want xrBeginFrame to run twice based on a single xrWaitFrame.
// During LoadMap RedrawViewports(false) is called twice to pump the render thread without a new game thread pump. This results in this function being
// called two additional times without corresponding xrWaitFrame calls from the game thread and therefore two extra xrBeginFrame calls. On SteamVR, at least,
// this then leaves us in a situation where our xrWaitFrame immediately returns forever.
// To avoid this we ensure that each xrWaitFrame is consumed by xrBeginFrame only once. We use the count of xrWaitFrame calls as an identifier. Before
// xrBeginFrame if the PipelinedFrameStateRHI wait count equals the incoming pipelined xrWaitFrame count then that xrWaitFrame has already been consumed,
// so we early out. Once a new game frame happens and a new xrWaitFrame the early out will fail and xrBeginFrame will happen.
if ((PipelinedFrameStateRHI.WaitCount == InFrameState.WaitCount) && bUseWaitCountToAvoidExtraXrBeginFrameCalls)
{
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/Teleporter/VREditorTeleporter.cpp:535
Scope (from outer to inner):
file
function float AVREditorTeleporter::GetSlideDelta_Implementation
Source code excerpt:
float AVREditorTeleporter::GetSlideDelta_Implementation(UVREditorInteractor* Interactor, const bool Axis)
{
static const FName SteamVR(TEXT("SteamVR"));
FVector2D SlideDelta = FVector2D::ZeroVector;
const bool bIsAbsolute = (VRMode->GetHMDDeviceType() == SteamVR);
if (bIsAbsolute)
{
SlideDelta = FVector2D(Interactor->GetTrackpadSlideDelta(0), Interactor->GetTrackpadSlideDelta(1));
}
else
{
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/UI/VREditorUISystem.cpp:279
Scope (from outer to inner):
file
function void UVREditorUISystem::OnPreviewInputAction
Source code excerpt:
const FViewportActionKeyInput& Action, bool& bOutIsInputCaptured, bool& bWasHandled)
{
static const FName SteamVR(TEXT("SteamVR"));
static const FName OculusHMD(TEXT("OculusHMD"));
UVREditorInteractor* VREditorInteractor = Cast<UVREditorInteractor>(Interactor);
// If we are releasing a UI panel that started drag from opening it.
if (VREditorInteractor && UIInteractor != nullptr && DraggingUI != nullptr && InteractorDraggingUI != nullptr && UIInteractor == InteractorDraggingUI && VREditorInteractor == UIInteractor &&
Action.Event == EInputEvent::IE_Released &&
((VRMode->GetHMDDeviceType() != SteamVR && Action.ActionType == ViewportWorldActionTypes::SelectAndMove) || (VRMode->GetHMDDeviceType() == SteamVR && Action.ActionType == VRActionTypes::ConfirmRadialSelection)))
{
bDragPanelFromOpen = false;
UViewportDragOperationComponent* DragOperationComponent = DraggingUI->GetDragOperationComponent();
if (DragOperationComponent)
{
DragOperationComponent->ClearDragOperation();
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/UI/VREditorUISystem.cpp:355
Scope (from outer to inner):
file
function void UVREditorUISystem::OnPreviewInputAction
Source code excerpt:
{
if ((VRMode->GetHMDDeviceType() == OculusHMD && Action.ActionType == ViewportWorldActionTypes::SelectAndMove) ||
(VRMode->GetHMDDeviceType() == SteamVR && Action.ActionType == VRActionTypes::ConfirmRadialSelection))
{
// If the radial menu is showing, select the currently highlighted button by pressing the trigger
if (QuickRadialMenu->GetCurrentlyHoveredButton().IsValid())
{
if ((Action.Event == IE_Pressed))
{
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/UI/VREditorUISystem.cpp:584
Scope (from outer to inner):
file
function void UVREditorUISystem::OnVRHoverUpdate
Source code excerpt:
void UVREditorUISystem::OnVRHoverUpdate(UViewportInteractor* Interactor, FVector& HoverImpactPoint, bool& bWasHandled)
{
static const FName SteamVR(TEXT("SteamVR"));
UVREditorInteractor* VREditorInteractor = Cast<UVREditorInteractor>( Interactor );
if( VREditorInteractor != nullptr )
{
if( !bWasHandled && Interactor->GetDraggingMode() == EViewportInteractionDraggingMode::Nothing )
{
FVector LaserPointerStart, LaserPointerEnd;
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/UI/VREditorUISystem.cpp:662
Scope (from outer to inner):
file
function void UVREditorUISystem::OnVRHoverUpdate
Source code excerpt:
if ( VREditorInteractor->IsTrackpadPositionValid( 1 ) )
{
const bool bIsAbsolute = ( GetOwner().GetHMDDeviceType() == SteamVR );
float ScrollDelta = 0.0f;
// Don't scroll if the radial menu is a number pad
if(( VREditorInteractor->IsTouchingTrackpad() || !bIsAbsolute) && !bRadialMenuIsNumpad)
{
if( bIsAbsolute )
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/UI/VREditorUISystem.cpp:681
Scope (from outer to inner):
file
function void UVREditorUISystem::OnVRHoverUpdate
Source code excerpt:
// If using a trackpad (Vive), invert scroll direction so that it feels more like scrolling on a mobile device
if( GetOwner().GetHMDDeviceType() == SteamVR )
{
ScrollDelta *= -1.0f;
}
if( !FMath::IsNearlyZero( ScrollDelta ) )
{
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/UI/VREditorUISystem.cpp:870
Scope (from outer to inner):
file
function void UVREditorUISystem::CreateUIs
Source code excerpt:
void UVREditorUISystem::CreateUIs()
{
static const FName SteamVR(TEXT("SteamVR"));
static const FName OculusHMD(TEXT("OculusHMD"));
const FIntPoint DefaultResolution( VREd::DefaultEditorUIResolutionX->GetInt(), VREd::DefaultEditorUIResolutionY->GetInt() );
const bool bShowUI = UVREditorMode::IsDebugModeEnabled();
{
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/UI/VREditorUISystem.cpp:885
Scope (from outer to inner):
file
function void UVREditorUISystem::CreateUIs
Source code excerpt:
InfoDisplayPanel->SetSlateWidget(*this, InfoDisplayPanelID, SNullWidget::NullWidget, Resolution, 20.0f, AVREditorBaseActor::EDockedTo::Nothing);
InfoDisplayPanel->ShowUI(bShowUI);
FVector RelativeOffset = VRMode->GetHMDDeviceType() == SteamVR ? FVector(5.0f, 0.0f, 0.0f) : FVector(5.0f, 0.0f, 10.0f);
InfoDisplayPanel->SetRelativeOffset(RelativeOffset);
InfoDisplayPanel->SetWindowMesh(VRMode->GetAssetContainer().WindowMesh);
FloatingUIs.Add(InfoDisplayPanelID, InfoDisplayPanel);
}
// Create the radial UI
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/UI/VREditorUISystem.cpp:895
Scope (from outer to inner):
file
function void UVREditorUISystem::CreateUIs
Source code excerpt:
QuickRadialMenu = GetOwner().SpawnTransientSceneActor<AVREditorRadialFloatingUI>(TEXT("QuickRadialmenu"), bWithSceneComponent);
FVector RelativeOffset = FVector::ZeroVector;
if (VRMode->GetHMDDeviceType() == SteamVR)
{
RelativeOffset = FVector(-5.0f, 0.0f, 5.0f);
}
else if (VRMode->GetHMDDeviceType() == OculusHMD)
{
RelativeOffset = FVector(0.0f, 0.0f, 3.0f);
#Loc: <Workspace>/Engine/Source/Editor/VREditor/Private/VREditorInteractor.cpp:72
Scope (from outer to inner):
file
namespace VREditorKeyNames
Source code excerpt:
namespace VREditorKeyNames
{
// @todo vreditor input: Ideally these would not be needed, but SteamVR fires off it's "trigger pressed" event
// well before the trigger is fully down (*click*)
static const FName MotionController_Left_PressedTriggerAxis( "MotionController_Left_PressedTriggerAxis" );
static const FName MotionController_Right_PressedTriggerAxis( "MotionController_Right_PressedTriggerAxis" );
static const FName MotionController_Left_FullyPressedTriggerAxis( "MotionController_Left_FullyPressedTriggerAxis" );
static const FName MotionController_Right_FullyPressedTriggerAxis( "MotionController_Right_FullyPressedTriggerAxis" );
}