diff --git a/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp b/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
index 9ea06e432ba7bd85d3730854a0bc1d59ebf044bd..79e6239a873a401cded6245778263005d4474f36 100644
--- a/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
+++ b/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
@@ -5,178 +5,312 @@
 #include "Game/IDisplayClusterGameManager.h"
 #include "GameFramework/InputSettings.h"
 #include "GameFramework/WorldSettings.h"
-#include "Input/IDisplayClusterInputManager.h"
 #include "Kismet/GameplayStatics.h"
 #include "DisplayClusterSettings.h"
-#include "HeadMountedDisplayFunctionLibrary.h"
+#include "IDisplayClusterConfigManager.h"
 #include "IDisplayCluster.h"
+#include "IXRTrackingSystem.h"
+#include "Engine/Engine.h"
+#include "Camera/CameraComponent.h"
 
 AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
 {
-  AutoPossessPlayer                       = EAutoReceiveInput::Player0; // Necessary for receiving motion controller events.
-
-  Movement                                = CreateDefaultSubobject<UFloatingPawnMovement>     (TEXT("Movement"));
-  Movement->UpdatedComponent              = RootComponent;
-  
-  RotatingMovement                        = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("RotatingMovement"));
-  RotatingMovement->UpdatedComponent      = RootComponent;
-  RotatingMovement->bRotationInLocalSpace = false;
-  RotatingMovement->PivotTranslation      = FVector::ZeroVector;
-  RotatingMovement->RotationRate          = FRotator::ZeroRotator;
-  
-  LeftMotionController                    = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("LeftMotionController"));
-  LeftMotionController->SetupAttachment    (RootComponent);
-  LeftMotionController->SetTrackingSource  (EControllerHand::Left);
-  LeftMotionController->SetShowDeviceModel (true );
-  LeftMotionController->SetVisibility      (false);
-
-  RightMotionController                   = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("RightMotionController"));
-  RightMotionController->SetupAttachment   (RootComponent);
-  RightMotionController->SetTrackingSource (EControllerHand::Right);
-  RightMotionController->SetShowDeviceModel(true );
-  RightMotionController->SetVisibility     (false);
-}
-
-void                    AVirtualRealityPawn::OnForward_Implementation   (float Value)
-{
-  AddMovementInput(Forward->GetForwardVector(), Value);
-}
-void                    AVirtualRealityPawn::OnRight_Implementation     (float Value)
-{
-  AddMovementInput(Forward->GetRightVector  (), Value);
-}
-void                    AVirtualRealityPawn::OnTurnRate_Implementation  (float Rate )
-{
-  if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
-  {
-    const FVector CameraLocation       = IDisplayCluster::Get().GetGameMgr()->GetActiveCamera()->GetComponentLocation();
-    RotatingMovement->PivotTranslation = RotatingMovement->UpdatedComponent->GetComponentTransform().InverseTransformPositionNoScale(CameraLocation);
-    RotatingMovement->RotationRate     = FRotator(RotatingMovement->RotationRate.Pitch, Rate * BaseTurnRate, 0.0f);
-  }
-  else
-  {
-    AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
-  }
-}
-void                    AVirtualRealityPawn::OnLookUpRate_Implementation(float Rate )
-{ 
-  if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
-  {
-    // User-centered projection causes simulation sickness on look up interaction hence not implemented.
-  }
-  else
-  {
-    AddControllerPitchInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
-  }
-}
-void                    AVirtualRealityPawn::OnFire_Implementation      (bool Pressed)
-{ 
-
-}
-void                    AVirtualRealityPawn::OnAction_Implementation    (bool Pressed, int32 Index)
-{ 
-
-}
-
-void                    AVirtualRealityPawn::BeginPlay                  ()
-{
-  Super::BeginPlay();
-  
-  bUseControllerRotationYaw   = true;
-  bUseControllerRotationPitch = true;
-  bUseControllerRotationRoll  = true;
-  
-  // Display cluster settings apply to all setups (PC, HMD, CAVE/ROLV) despite the unfortunate name due to being an UE4 internal.
-  TArray<AActor*> SettingsActors;
-  UGameplayStatics::GetAllActorsOfClass(GetWorld(), ADisplayClusterSettings::StaticClass(), SettingsActors);
-  if (SettingsActors.Num() > 0)
-  {  
-    ADisplayClusterSettings* Settings = Cast<ADisplayClusterSettings>(SettingsActors[0]);
-    Movement->MaxSpeed     = Settings->MovementMaxSpeed    ;
-    Movement->Acceleration = Settings->MovementAcceleration;
-    Movement->Deceleration = Settings->MovementDeceleration;
-    Movement->TurningBoost = Settings->MovementTurningBoost;
-    BaseTurnRate           = Settings->RotationSpeed       ;
-  }
-
-  if      (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
-  {
-    UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("TurnRate"  )), EKeys::MouseX));
-    UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("LookUpRate")), EKeys::MouseY));
-
-    // Requires a scene node called flystick in the config.
-    Flystick  = IDisplayCluster::Get().GetGameMgr()->GetNodeById(TEXT("flystick"));
-
-    Forward   = Flystick;
-    LeftHand  = Flystick;
-    RightHand = Flystick;
-  }
-  else if (UHeadMountedDisplayFunctionLibrary::IsHeadMountedDisplayConnected())
-  {
-    UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("TurnRate"  )), EKeys::MouseX));
-    UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("LookUpRate")), EKeys::MouseY));
-
-    LeftMotionController ->SetVisibility(true);
-    RightMotionController->SetVisibility(true);
-    
-    Forward   = LeftMotionController ;
-    LeftHand  = LeftMotionController ;
-    RightHand = RightMotionController;
-  }
-  else
-  {
-    Forward   = RootComponent;
-    LeftHand  = RootComponent;
-    RightHand = RootComponent;
-  }
-}
-void                    AVirtualRealityPawn::Tick                       (float DeltaSeconds)
+	AutoPossessPlayer = EAutoReceiveInput::Player0; // Necessary for receiving motion controller events.
+
+	Movement = CreateDefaultSubobject<UFloatingPawnMovement>(TEXT("Movement"));
+	Movement->UpdatedComponent = RootComponent;
+
+	RotatingMovement = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("RotatingMovement"));
+	RotatingMovement->UpdatedComponent = RootComponent;
+	RotatingMovement->bRotationInLocalSpace = false;
+	RotatingMovement->PivotTranslation = FVector::ZeroVector;
+	RotatingMovement->RotationRate = FRotator::ZeroRotator;
+
+	HmdLeftMotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdLeftMotionController"));
+	HmdLeftMotionController->SetupAttachment(RootComponent);
+	HmdLeftMotionController->SetTrackingSource(EControllerHand::Left);
+	HmdLeftMotionController->SetShowDeviceModel(true);
+	HmdLeftMotionController->SetVisibility(false);
+
+	HmdRightMotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdRightMotionController"));
+	HmdRightMotionController->SetupAttachment(RootComponent);
+	HmdRightMotionController->SetTrackingSource(EControllerHand::Right);
+	HmdRightMotionController->SetShowDeviceModel(true);
+	HmdRightMotionController->SetVisibility(false);
+}
+
+void AVirtualRealityPawn::OnForward_Implementation(float Value)
+{
+	// Check if this function triggers correctly on ROLV.
+	if (NavigationMode == EVRNavigationModes::Nav_Mode_Fly || IsDesktopMode() || IsHeadMountedMode())
+	{
+		AddMovementInput(RightHand->GetForwardVector(), Value);
+	}
+}
+
+void AVirtualRealityPawn::OnRight_Implementation(float Value)
+{
+	if (NavigationMode == EVRNavigationModes::Nav_Mode_Fly || IsDesktopMode() || IsHeadMountedMode())
+	{
+		AddMovementInput(RightHand->GetRightVector(), Value);
+	}
+}
+
+void AVirtualRealityPawn::OnTurnRate_Implementation(float Rate)
+{
+	//if (IsRoomMountedMode())
+	//{
+	//	//const FVector CameraLocation = IDisplayCluster::Get().GetGameMgr()->GetActiveCamera()->GetComponentLocation();
+	//	//RotatingMovement->PivotTranslation = RotatingMovement
+	//	//                                     ->UpdatedComponent->GetComponentTransform().
+	//	//                                     InverseTransformPositionNoScale(CameraLocation);
+	//	//RotatingMovement->RotationRate = FRotator(RotatingMovement->RotationRate.Pitch, Rate * BaseTurnRate, 0.0f);
+
+	//}
+	//else
+	//{
+	//	AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
+	//}
+	AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
+}
+
+void AVirtualRealityPawn::OnLookUpRate_Implementation(float Rate)
+{
+	if (IsRoomMountedMode())
+	{
+		// User-centered projection causes simulation sickness on look up interaction hence not implemented.
+	}
+	else
+	{
+		AddControllerPitchInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
+	}
+}
+
+void AVirtualRealityPawn::OnFire_Implementation(bool Pressed)
+{
+}
+
+void AVirtualRealityPawn::OnAction_Implementation(bool Pressed, int32 Index)
+{
+}
+
+bool AVirtualRealityPawn::IsDesktopMode()
+{
+	return !IsRoomMountedMode() && !IsHeadMountedMode();
+}
+
+bool AVirtualRealityPawn::IsRoomMountedMode()
+{
+	return IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster;
+}
+
+bool AVirtualRealityPawn::IsHeadMountedMode()
+{
+	return GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed();
+}
+
+FString AVirtualRealityPawn::GetNodeName()
+{
+	return IsRoomMountedMode() ? IDisplayCluster::Get().GetClusterMgr()->GetNodeId() : FString(TEXT("Localhost"));
+}
+
+float AVirtualRealityPawn::GetEyeDistance()
+{
+	return IDisplayCluster::Get().GetConfigMgr()->GetConfigStereo().EyeDist;
+}
+
+float AVirtualRealityPawn::GetBaseTurnRate() const
+{
+	return BaseTurnRate;
+}
+
+void AVirtualRealityPawn::SetBaseTurnRate(float Value)
+{
+	BaseTurnRate =  Value;
+}
+
+UFloatingPawnMovement* AVirtualRealityPawn::GetFloatingPawnMovement()
+{
+	return Movement;
+}
+
+URotatingMovementComponent* AVirtualRealityPawn::GetRotatingMovementComponent()
+{
+	return RotatingMovement;
+}
+
+UDisplayClusterSceneComponent* AVirtualRealityPawn::GetFlystickComponent()
+{
+	return Flystick;
+}
+
+UMotionControllerComponent* AVirtualRealityPawn::GetHmdLeftMotionControllerComponent()
+{
+	return HmdLeftMotionController;
+}
+
+UMotionControllerComponent* AVirtualRealityPawn::GetHmdRightMotionControllerComponent()
+{
+	return HmdRightMotionController;
+}
+
+USceneComponent* AVirtualRealityPawn::GetHeadComponent()
+{
+	return Head;
+}
+
+USceneComponent* AVirtualRealityPawn::GetLeftHandComponent()
+{
+	return LeftHand;
+}
+
+USceneComponent* AVirtualRealityPawn::GetRightHandComponent()
+{
+	return RightHand;
+}
+
+USceneComponent* AVirtualRealityPawn::GetCaveOriginComponent()
+{
+	return CaveOrigin;
+}
+
+USceneComponent* AVirtualRealityPawn::GetCaveCenterComponent()
+{
+	return CaveCenter;
+}
+
+USceneComponent* AVirtualRealityPawn::GetShutterGlassesComponent()
+{
+	return ShutterGlasses;
+}
+
+UDisplayClusterSceneComponent* AVirtualRealityPawn::GetClusterComponent(const FString& Name)
+{
+	return IDisplayCluster::Get().GetGameMgr()->GetNodeById(Name);
+}
+
+void AVirtualRealityPawn::BeginPlay()
+{
+	Super::BeginPlay();
+
+	bUseControllerRotationYaw = true;
+	bUseControllerRotationPitch = true;
+	bUseControllerRotationRoll = true;
+
+	// Display cluster settings apply to all setups (PC, HMD, CAVE/ROLV) despite the unfortunate name due to being an UE4 internal.
+	TArray<AActor*> SettingsActors;
+	UGameplayStatics::GetAllActorsOfClass(GetWorld(), ADisplayClusterSettings::StaticClass(), SettingsActors);
+	if (SettingsActors.Num() > 0)
+	{
+		ADisplayClusterSettings* Settings = Cast<ADisplayClusterSettings>(SettingsActors[0]);
+		Movement->MaxSpeed = Settings->MovementMaxSpeed;
+		Movement->Acceleration = Settings->MovementAcceleration;
+		Movement->Deceleration = Settings->MovementDeceleration;
+		Movement->TurningBoost = Settings->MovementTurningBoost;
+		BaseTurnRate = Settings->RotationSpeed;
+	}
+
+	if (IsRoomMountedMode())
+	{
+		UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("TurnRate", EKeys::MouseX));
+		UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("LookUpRate", EKeys::MouseY));
+
+		InitComponentReferences();
+
+		RootComponent->SetWorldLocation(FVector(0, 2, 0), false, nullptr, ETeleportType::None);
+	}
+	else if (IsHeadMountedMode())
+	{
+		UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("TurnRate", EKeys::MouseX));
+		UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("LookUpRate", EKeys::MouseY));
+
+		HmdLeftMotionController->SetVisibility(true);
+		HmdRightMotionController->SetVisibility(true);
+
+		LeftHand = HmdLeftMotionController;
+		RightHand = HmdRightMotionController;
+		Head = GetCameraComponent();
+	}
+	else
+	{
+		LeftHand = RootComponent;
+		RightHand = RootComponent;
+		Head = GetCameraComponent();
+	}
+}
+
+void AVirtualRealityPawn::Tick(float DeltaSeconds)
 {
 	Super::Tick(DeltaSeconds);
-  
-  // Flystick might not be available at start, hence is checked every frame.
-  if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster && !Flystick)
-  { 
-    // Requires a scene node called flystick in the config.
-    Flystick  = IDisplayCluster::Get().GetGameMgr()->GetNodeById(TEXT("flystick"));
-
-    Forward   = Flystick;
-    LeftHand  = Flystick;
-    RightHand = Flystick;
-  }
-}
-void                    AVirtualRealityPawn::BeginDestroy               ()
-{
-  Super::BeginDestroy();
-}
-
-void                    AVirtualRealityPawn::SetupPlayerInputComponent  (UInputComponent* PlayerInputComponent)
-{
-  check(PlayerInputComponent);
-  Super::SetupPlayerInputComponent(PlayerInputComponent);
-  if (PlayerInputComponent)
-  {
-    PlayerInputComponent->BindAxis                   ("MoveForward"             , this, &AVirtualRealityPawn::OnForward             );
-    PlayerInputComponent->BindAxis                   ("MoveRight"               , this, &AVirtualRealityPawn::OnRight               );
-    PlayerInputComponent->BindAxis                   ("TurnRate"                , this, &AVirtualRealityPawn::OnTurnRate            );
-    PlayerInputComponent->BindAxis                   ("LookUpRate"              , this, &AVirtualRealityPawn::OnLookUpRate          );
-
-    PlayerInputComponent->BindAction<FFireDelegate>  ("Fire"       , IE_Pressed , this, &AVirtualRealityPawn::OnFire      , true    );
-    PlayerInputComponent->BindAction<FActionDelegate>("Action1"    , IE_Pressed , this, &AVirtualRealityPawn::OnAction    , true , 1);
-    PlayerInputComponent->BindAction<FActionDelegate>("Action2"    , IE_Pressed , this, &AVirtualRealityPawn::OnAction    , true , 2);
-    PlayerInputComponent->BindAction<FActionDelegate>("Action3"    , IE_Pressed , this, &AVirtualRealityPawn::OnAction    , true , 3);
-    PlayerInputComponent->BindAction<FActionDelegate>("Action4"    , IE_Pressed , this, &AVirtualRealityPawn::OnAction    , true , 4);
-    PlayerInputComponent->BindAction<FActionDelegate>("Action5"    , IE_Pressed , this, &AVirtualRealityPawn::OnAction    , true , 5);
-    
-    PlayerInputComponent->BindAction<FFireDelegate>  ("Fire"       , IE_Released, this, &AVirtualRealityPawn::OnFire      , false   );
-    PlayerInputComponent->BindAction<FActionDelegate>("Action1"    , IE_Released, this, &AVirtualRealityPawn::OnAction    , false, 1);
-    PlayerInputComponent->BindAction<FActionDelegate>("Action2"    , IE_Released, this, &AVirtualRealityPawn::OnAction    , false, 2);
-    PlayerInputComponent->BindAction<FActionDelegate>("Action3"    , IE_Released, this, &AVirtualRealityPawn::OnAction    , false, 3);
-    PlayerInputComponent->BindAction<FActionDelegate>("Action4"    , IE_Released, this, &AVirtualRealityPawn::OnAction    , false, 4);
-    PlayerInputComponent->BindAction<FActionDelegate>("Action5"    , IE_Released, this, &AVirtualRealityPawn::OnAction    , false, 5);
-  }
-}
-UPawnMovementComponent* AVirtualRealityPawn::GetMovementComponent       () const
-{
-  return Movement;
+
+	// Components might not be available at start, hence is checked every frame.
+	InitComponentReferences();
+}
+
+void AVirtualRealityPawn::BeginDestroy()
+{
+	Super::BeginDestroy();
+}
+
+void AVirtualRealityPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
+{
+	check(PlayerInputComponent);
+	Super::SetupPlayerInputComponent(PlayerInputComponent);
+	if (PlayerInputComponent)
+	{
+		PlayerInputComponent->BindAxis("MoveForward", this, &AVirtualRealityPawn::OnForward);
+		PlayerInputComponent->BindAxis("MoveRight", this, &AVirtualRealityPawn::OnRight);
+		PlayerInputComponent->BindAxis("TurnRate", this, &AVirtualRealityPawn::OnTurnRate);
+		PlayerInputComponent->BindAxis("LookUpRate", this, &AVirtualRealityPawn::OnLookUpRate);
+
+		// The button names are based on the definitions in aixcave_422.cfg.
+		PlayerInputComponent->BindAction<FFireDelegate>("nDisplayButton0", IE_Pressed, this,
+		                                                &AVirtualRealityPawn::OnFire, true);
+		PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton1", IE_Pressed, this,
+		                                                  &AVirtualRealityPawn::OnAction, true, 1);
+		PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton2", IE_Pressed, this,
+		                                                  &AVirtualRealityPawn::OnAction, true, 2);
+		PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton3", IE_Pressed, this,
+		                                                  &AVirtualRealityPawn::OnAction, true, 3);
+		PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton4", IE_Pressed, this,
+		                                                  &AVirtualRealityPawn::OnAction, true, 4);
+		PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton5", IE_Pressed, this,
+		                                                  &AVirtualRealityPawn::OnAction, true, 5);
+
+		PlayerInputComponent->BindAction<FFireDelegate>("nDisplayButton0", IE_Released, this,
+		                                                &AVirtualRealityPawn::OnFire, false);
+		PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton1", IE_Released, this,
+		                                                  &AVirtualRealityPawn::OnAction, false, 1);
+		PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton2", IE_Released, this,
+		                                                  &AVirtualRealityPawn::OnAction, false, 2);
+		PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton3", IE_Released, this,
+		                                                  &AVirtualRealityPawn::OnAction, false, 3);
+		PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton4", IE_Released, this,
+		                                                  &AVirtualRealityPawn::OnAction, false, 4);
+		PlayerInputComponent->BindAction<FActionDelegate>("nDisplayButton5", IE_Released, this,
+		                                                  &AVirtualRealityPawn::OnAction, false, 5);
+	}
+}
+
+UPawnMovementComponent* AVirtualRealityPawn::GetMovementComponent() const
+{
+	return Movement;
+}
+
+void AVirtualRealityPawn::InitComponentReferences()
+{
+	if (!IsRoomMountedMode()) return;
+	if (!CaveOrigin) CaveOrigin = GetClusterComponent("cave_origin");
+	if (!CaveCenter) CaveCenter = GetClusterComponent("cave_center");
+	if (!ShutterGlasses) {
+		ShutterGlasses = GetClusterComponent("shutter_glasses");
+		Head = ShutterGlasses;
+	}
+	if (!Flystick)
+	{
+		Flystick = GetClusterComponent("flystick");
+
+		LeftHand = Flystick;
+		RightHand = Flystick;
+	}
 }
diff --git a/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h b/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
index 0569fdfa0a747634943faa43be1555cac59c2e60..c6a3bfff7676109d6376497671d35f449429da19 100644
--- a/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
+++ b/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
@@ -10,44 +10,105 @@
 
 #include "VirtualRealityPawn.generated.h"
 
+UENUM(BlueprintType)
+enum class EVRNavigationModes : uint8
+{
+	Nav_Mode_None UMETA(DisplayName = "Navigation Mode None"),
+	Nav_Mode_Fly UMETA(DisplayName = "Navigation Mode Fly")
+};
+
 UCLASS()
 class DISPLAYCLUSTEREXTENSIONS_API AVirtualRealityPawn : public ADisplayClusterPawn
 {
-  GENERATED_UCLASS_BODY()
+	GENERATED_UCLASS_BODY()
 
 public:
-  UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnForward   (float Value  );
-  UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnRight     (float Value  );
-  UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnTurnRate  (float Rate   );
-  UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnLookUpRate(float Rate   );
-  UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnFire      (bool  Pressed);
-  UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnAction    (bool  Pressed, int32 Index);
+	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnForward(float Value);
+	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnRight(float Value);
+	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnTurnRate(float Rate);
+	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnLookUpRate(float Rate);
+	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnFire(bool Pressed);
+	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnAction(bool Pressed, int32 Index);
+
+	UFUNCTION(BlueprintPure, Category = "Pawn") static bool IsDesktopMode();
+	UFUNCTION(BlueprintPure, Category = "Pawn") static bool IsRoomMountedMode();
+	UFUNCTION(BlueprintPure, Category = "Pawn") static bool IsHeadMountedMode();
+
+	UFUNCTION(BlueprintPure, Category = "Pawn") static FString GetNodeName();
+	UFUNCTION(BlueprintPure, Category = "Pawn") static float GetEyeDistance();
+
+	UFUNCTION(Category = "Pawn") float GetBaseTurnRate() const;
+	UFUNCTION(Category = "Pawn") void SetBaseTurnRate(float Value);
+	UFUNCTION(Category = "Pawn") UFloatingPawnMovement* GetFloatingPawnMovement();
+	UFUNCTION(Category = "Pawn") URotatingMovementComponent* GetRotatingMovementComponent();
+
+	//Bunch of Getter Functions for components to avoid users having to know the names
+
+	UFUNCTION(Category = "Pawn") UDisplayClusterSceneComponent* GetFlystickComponent();
+	UFUNCTION(Category = "Pawn") UMotionControllerComponent* GetHmdLeftMotionControllerComponent();
+	UFUNCTION(Category = "Pawn") UMotionControllerComponent* GetHmdRightMotionControllerComponent();
+
+	UFUNCTION(Category = "Pawn") USceneComponent* GetHeadComponent();
+	UFUNCTION(Category = "Pawn") USceneComponent* GetLeftHandComponent();
+	UFUNCTION(Category = "Pawn") USceneComponent* GetRightHandComponent();
+
+	UFUNCTION(Category = "Pawn") USceneComponent* GetCaveOriginComponent();
+	UFUNCTION(Category = "Pawn") USceneComponent* GetCaveCenterComponent();
+	UFUNCTION(Category = "Pawn") USceneComponent* GetShutterGlassesComponent();
+
+	//Get Compenent of Display Cluster by it's name, which is specified in the nDisplay config
+	UFUNCTION(BlueprintPure, BlueprintCallable, Category = "Pawn") static UDisplayClusterSceneComponent* GetClusterComponent(
+		const FString& Name);
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EVRNavigationModes NavigationMode =
+		EVRNavigationModes::Nav_Mode_Fly;
 
 protected:
-  DECLARE_DELEGATE_OneParam (FFireDelegate  , bool);
-  DECLARE_DELEGATE_TwoParams(FActionDelegate, bool, int32);
-
-  virtual void                    BeginPlay                ()                                            override;
-  virtual void                    Tick                     (float            DeltaSeconds        )       override;
-  virtual void                    BeginDestroy             ()                                            override;
-  virtual void                    SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)       override;
-  virtual UPawnMovementComponent* GetMovementComponent     ()                                      const override;
-  
-  UPROPERTY(EditAnywhere   , BlueprintReadWrite, Category = "Pawn", meta = (AllowPrivateAccess = "true")) float                          BaseTurnRate          = 45.0f  ;
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) UFloatingPawnMovement*         Movement              = nullptr;
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) URotatingMovementComponent*    RotatingMovement      = nullptr;
-  
-  // Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. CAVE/ROLV flystick.
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) UDisplayClusterSceneComponent* Flystick              = nullptr;
-  // Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. HMD left  motion controller.
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) UMotionControllerComponent*    LeftMotionController  = nullptr;
-  // Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. HMD right motion controller.
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) UMotionControllerComponent*    RightMotionController = nullptr;
-
-  // PC: RootComponent, HMD: LeftMotionController , CAVE/ROLV: Flystick. Movement follows this component.
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) USceneComponent*               Forward               = nullptr;
-  // PC: RootComponent, HMD: LeftMotionController , CAVE/ROLV: Flystick. Useful for line trace (e.g. for holding objects).
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) USceneComponent*               LeftHand              = nullptr;
-  // PC: RootComponent, HMD: RightMotionController, CAVE/ROLV: Flystick. Useful for line trace (e.g. for holding objects).
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) USceneComponent*               RightHand             = nullptr;
+	DECLARE_DELEGATE_OneParam(FFireDelegate, bool);
+	DECLARE_DELEGATE_TwoParams(FActionDelegate, bool, int32);
+
+	virtual void BeginPlay() override;
+	virtual void Tick(float DeltaSeconds) override;
+	virtual void BeginDestroy() override;
+	virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override;
+	virtual UPawnMovementComponent* GetMovementComponent() const override;
+
+	UPROPERTY(EditAnywhere , BlueprintReadWrite, Category = "Pawn", meta = (AllowPrivateAccess = "true")) float
+	BaseTurnRate = 45.0f;
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	UFloatingPawnMovement* Movement = nullptr;
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	URotatingMovementComponent* RotatingMovement = nullptr;
+
+	// Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. CAVE/ROLV flystick.
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	UDisplayClusterSceneComponent* Flystick = nullptr;
+	// Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. HMD left  motion controller.
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	UMotionControllerComponent* HmdLeftMotionController = nullptr;
+	// Use only when handling cross-device (PC, HMD, CAVE/ROLV) compatibility manually. HMD right motion controller.
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	UMotionControllerComponent* HmdRightMotionController = nullptr;
+
+	// PC: Camera, HMD: Camera, CAVE/ROLV: Shutter glasses.
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	USceneComponent* Head = nullptr;
+	// PC: RootComponent, HMD: HmdLeftMotionController , CAVE/ROLV: Flystick. Useful for line trace (e.g. for holding objects).
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	USceneComponent* LeftHand = nullptr;
+	// PC: RootComponent, HMD: HmdRightMotionController, CAVE/ROLV: Flystick. Useful for line trace (e.g. for holding objects).
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	USceneComponent* RightHand = nullptr;
+	
+	// Holding the Cave Origin Component that is attached to this Pawn
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	USceneComponent* CaveOrigin = nullptr;
+	// Holding the Cave Center Component that is attached to this Pawn
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	USceneComponent* CaveCenter = nullptr;
+	// Holding the Shutter Glasses Component that is attached to this Pawn
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true"))
+	USceneComponent* ShutterGlasses = nullptr;
+private:
+	void InitComponentReferences();
 };