From 036d945fcecad0a336bbd83f82f7fc67334400e2 Mon Sep 17 00:00:00 2001
From: Sebastian Pape <Sebastian.Pape@rwth-aachen.de>
Date: Fri, 23 Aug 2019 13:27:25 +0200
Subject: [PATCH] Reformatting, Refactoring and adding some convenience
 functions

---
 .../Private/VirtualRealityPawn.cpp            | 423 ++++++++++--------
 .../Public/VirtualRealityPawn.h               | 138 +++---
 2 files changed, 325 insertions(+), 236 deletions(-)

diff --git a/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp b/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
index 4f272da0..1ca09b5c 100644
--- a/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
+++ b/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
@@ -5,255 +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.
+	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);
+	Movement = CreateDefaultSubobject<UFloatingPawnMovement>(TEXT("Movement"));
+	Movement->UpdatedComponent = RootComponent;
 
-  HmdRightMotionController                   = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdRightMotionController"));
-  HmdRightMotionController->SetupAttachment   (RootComponent);
-  HmdRightMotionController->SetTrackingSource (EControllerHand::Right);
-  HmdRightMotionController->SetShowDeviceModel(true );
-  HmdRightMotionController->SetVisibility     (false);
+	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)
+void AVirtualRealityPawn::OnForward_Implementation(float Value)
 {
-  if (NavigationMode == EVRNavigationModes::NAV_MODE_FLY || IsDesktopMode() || IsHeadMountedMode()) // Check if this function triggers correctly on ROLV.
-  {
-    AddMovementInput(Forward->GetForwardVector(), 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)
+
+void AVirtualRealityPawn::OnRight_Implementation(float Value)
 {
-  if (NavigationMode == EVRNavigationModes::NAV_MODE_FLY || IsDesktopMode() || IsHeadMountedMode())
-  {
-    AddMovementInput(Forward->GetRightVector(), Value);
-  }
+	if (NavigationMode == EVRNavigationModes::Nav_Mode_Fly || IsDesktopMode() || IsHeadMountedMode())
+	{
+		AddMovementInput(RightHand->GetRightVector(), Value);
+	}
 }
-void                           AVirtualRealityPawn::OnTurnRate_Implementation           (float Rate )
+
+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);
-  }
+	//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::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::OnFire_Implementation(bool Pressed)
+{
 }
-void                           AVirtualRealityPawn::OnAction_Implementation             (bool Pressed, int32 Index)
-{ 
 
+void AVirtualRealityPawn::OnAction_Implementation(bool Pressed, int32 Index)
+{
 }
-                               
-bool                           AVirtualRealityPawn::IsDesktopMode                       ()
+
+bool AVirtualRealityPawn::IsDesktopMode()
 {
-  return !IsRoomMountedMode() && !IsHeadMountedMode();
+	return !IsRoomMountedMode() && !IsHeadMountedMode();
 }
-bool                           AVirtualRealityPawn::IsRoomMountedMode                   ()
+
+bool AVirtualRealityPawn::IsRoomMountedMode()
 {
-  return IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster;
+	return IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster;
 }
-bool                           AVirtualRealityPawn::IsHeadMountedMode                   ()
+
+bool AVirtualRealityPawn::IsHeadMountedMode()
 {
-  return GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed();
+	return GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed();
 }
 
-FString                        AVirtualRealityPawn::GetNodeName                         ()
+FString AVirtualRealityPawn::GetNodeName()
 {
-  return IsRoomMountedMode() ? IDisplayCluster::Get().GetClusterMgr()->GetNodeId() : FString(TEXT("Localhost"));
+	return IsRoomMountedMode() ? IDisplayCluster::Get().GetClusterMgr()->GetNodeId() : FString(TEXT("Localhost"));
 }
-float                          AVirtualRealityPawn::GetEyeDistance()
+
+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 IDisplayCluster::Get().GetConfigMgr()->GetConfigStereo().EyeDist;
+	return RotatingMovement;
 }
 
-float                          AVirtualRealityPawn::GetBaseTurnRate                     () const
+UDisplayClusterSceneComponent* AVirtualRealityPawn::GetFlystickComponent()
 {
-  return BaseTurnRate;
+	return Flystick;
 }
-UFloatingPawnMovement*         AVirtualRealityPawn::GetFloatingPawnMovement             ()
+
+UMotionControllerComponent* AVirtualRealityPawn::GetHmdLeftMotionControllerComponent()
 {
-  return Movement;
+	return HmdLeftMotionController;
 }
-URotatingMovementComponent*    AVirtualRealityPawn::GetRotatingMovementComponent        ()
+
+UMotionControllerComponent* AVirtualRealityPawn::GetHmdRightMotionControllerComponent()
 {
-  return RotatingMovement;
+	return HmdRightMotionController;
 }
 
-UDisplayClusterSceneComponent* AVirtualRealityPawn::GetFlystickComponent                ()
+USceneComponent* AVirtualRealityPawn::GetHeadComponent()
 {
-  return Flystick;
+	return Head;
 }
-UMotionControllerComponent*    AVirtualRealityPawn::GetHmdLeftMotionControllerComponent ()
+
+USceneComponent* AVirtualRealityPawn::GetLeftHandComponent()
 {
-  return HmdLeftMotionController;
+	return LeftHand;
 }
-UMotionControllerComponent*    AVirtualRealityPawn::GetHmdRightMotionControllerComponent()
+
+USceneComponent* AVirtualRealityPawn::GetRightHandComponent()
 {
-  return HmdRightMotionController;
+	return RightHand;
 }
 
-USceneComponent*               AVirtualRealityPawn::GetForwardComponent                 ()
+USceneComponent* AVirtualRealityPawn::GetCaveOriginComponent()
 {
-  return Forward;
+	return CaveOrigin;
 }
-USceneComponent*               AVirtualRealityPawn::GetLeftHandComponent                ()
+
+USceneComponent* AVirtualRealityPawn::GetCaveCenterComponent()
 {
-  return LeftHand;
+	return CaveCenter;
 }
-USceneComponent*               AVirtualRealityPawn::GetRightHandComponent               ()
+
+USceneComponent* AVirtualRealityPawn::GetShutterGlassesComponent()
 {
-  return RightHand;
+	return ShutterGlasses;
 }
 
-UDisplayClusterSceneComponent* AVirtualRealityPawn::GetClusterComponent                 (const FString& name)
+UDisplayClusterSceneComponent* AVirtualRealityPawn::GetClusterComponent(const FString& Name)
 {
-  return IDisplayCluster::Get().GetGameMgr()->GetNodeById(name);
+	return IDisplayCluster::Get().GetGameMgr()->GetNodeById(Name);
 }
 
-void                           AVirtualRealityPawn::BeginPlay                           ()
+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       ;
-  }
+	Super::BeginPlay();
+
+	bUseControllerRotationYaw = true;
+	bUseControllerRotationPitch = true;
+	bUseControllerRotationRoll = true;
 
-  if      (IsRoomMountedMode())
-  {
-    UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("TurnRate"  )), EKeys::MouseX));
-    UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("LookUpRate")), EKeys::MouseY));
+	// 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;
+	}
 
-    // Requires a scene node called flystick in the config.
-    Flystick  = GetClusterComponent(TEXT("flystick"));
+	if (IsRoomMountedMode())
+	{
+		UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("TurnRate", EKeys::MouseX));
+		UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping("LookUpRate", EKeys::MouseY));
 
-    Forward   = Flystick;
-    LeftHand  = Flystick;
-    RightHand = Flystick;
+		InitComponentReferences();
 
-    RootComponent->SetWorldLocation(FVector(0, 2, 0), false, nullptr, ETeleportType::None);
-  }
-  else if (IsHeadMountedMode())
-  {
-    UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("TurnRate"  )), EKeys::MouseX));
-    UInputSettings::GetInputSettings()->RemoveAxisMapping(FInputAxisKeyMapping(FName(TEXT("LookUpRate")), EKeys::MouseY));
+		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);
-    
-    Forward   = HmdLeftMotionController ;
-    LeftHand  = HmdLeftMotionController ;
-    RightHand = HmdRightMotionController;
-  }
-  else
-  {
-    Forward   = RootComponent;
-    LeftHand  = RootComponent;
-    RightHand = RootComponent;
-  }
+		HmdLeftMotionController->SetVisibility(true);
+		HmdRightMotionController->SetVisibility(true);
+
+		LeftHand = HmdLeftMotionController;
+		RightHand = HmdRightMotionController;
+		Head = GetCameraComponent();
+	}
+	else
+	{
+		LeftHand = RootComponent;
+		RightHand = RootComponent;
+		Head = GetCameraComponent();
+	}
 }
-void                           AVirtualRealityPawn::Tick                                (float DeltaSeconds)
+
+void AVirtualRealityPawn::Tick(float DeltaSeconds)
 {
 	Super::Tick(DeltaSeconds);
-  
-  // Flystick might not be available at start, hence is checked every frame.
-  if (IsRoomMountedMode() && !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);
-
-    // 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;
+
+	// 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 (!CaveOrigin) CaveCenter = GetClusterComponent("cave_center");
+	if (!CaveOrigin) {
+		ShutterGlasses = GetClusterComponent("shutter_glasses");
+		Head = Flystick;
+	}
+	if (!Flystick)
+	{
+		Flystick = GetClusterComponent("flystick");
+
+		LeftHand = Flystick;
+		RightHand = Flystick;
+	}
 }
diff --git a/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h b/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
index 2fab742d..c6a3bfff 100644
--- a/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
+++ b/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
@@ -11,72 +11,104 @@
 #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")
+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();
 
-  UFUNCTION(BlueprintCallable, Category = "Pawn") bool                           IsDesktopMode                       ();
-  UFUNCTION(BlueprintCallable, Category = "Pawn") bool                           IsRoomMountedMode                   ();
-  UFUNCTION(BlueprintCallable, Category = "Pawn") bool                           IsHeadMountedMode                   ();
+	//Bunch of Getter Functions for components to avoid users having to know the names
 
-  UFUNCTION(BlueprintCallable, Category = "Pawn") FString                        GetNodeName                         ();
-  UFUNCTION(BlueprintCallable, Category = "Pawn") float                          GetEyeDistance                      ();
+	UFUNCTION(Category = "Pawn") UDisplayClusterSceneComponent* GetFlystickComponent();
+	UFUNCTION(Category = "Pawn") UMotionControllerComponent* GetHmdLeftMotionControllerComponent();
+	UFUNCTION(Category = "Pawn") UMotionControllerComponent* GetHmdRightMotionControllerComponent();
 
-  UFUNCTION(BlueprintCallable, Category = "Pawn") float                          GetBaseTurnRate                     () const;
-  UFUNCTION(BlueprintCallable, Category = "Pawn") UFloatingPawnMovement*         GetFloatingPawnMovement             ();
-  UFUNCTION(BlueprintCallable, Category = "Pawn") URotatingMovementComponent*    GetRotatingMovementComponent        ();
+	UFUNCTION(Category = "Pawn") USceneComponent* GetHeadComponent();
+	UFUNCTION(Category = "Pawn") USceneComponent* GetLeftHandComponent();
+	UFUNCTION(Category = "Pawn") USceneComponent* GetRightHandComponent();
 
-  UFUNCTION(BlueprintCallable, Category = "Pawn") UDisplayClusterSceneComponent* GetFlystickComponent                ();
-  UFUNCTION(BlueprintCallable, Category = "Pawn") UMotionControllerComponent*    GetHmdLeftMotionControllerComponent ();
-  UFUNCTION(BlueprintCallable, Category = "Pawn") UMotionControllerComponent*    GetHmdRightMotionControllerComponent();
-  
-  UFUNCTION(BlueprintCallable, Category = "Pawn") USceneComponent*               GetForwardComponent                 ();
-  UFUNCTION(BlueprintCallable, Category = "Pawn") USceneComponent*               GetLeftHandComponent                ();
-  UFUNCTION(BlueprintCallable, Category = "Pawn") USceneComponent*               GetRightHandComponent               ();
+	UFUNCTION(Category = "Pawn") USceneComponent* GetCaveOriginComponent();
+	UFUNCTION(Category = "Pawn") USceneComponent* GetCaveCenterComponent();
+	UFUNCTION(Category = "Pawn") USceneComponent* GetShutterGlassesComponent();
 
-  UFUNCTION(BlueprintCallable, Category = "Pawn") UDisplayClusterSceneComponent* GetClusterComponent                 (const FString& name);
+	//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;
+	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*    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: RootComponent, HMD: HmdLeftMotionController , CAVE/ROLV: Flystick. Movement follows this component.
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly , Category = "Pawn", meta = (AllowPrivateAccess = "true")) USceneComponent*               Forward               = 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;
+	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();
 };
-- 
GitLab