diff --git a/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp b/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
index 1bcdfdec087afd30462f1cc503afd885c200c720..8281ebbb15dff70fbc6bb41303f81854255bf40c 100644
--- a/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
+++ b/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
@@ -12,52 +12,60 @@
 
 AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
 {
-  MovementComponent                        = CreateDefaultSubobject<UFloatingPawnMovement>     (TEXT("MovementComponent0"));
-  MovementComponent->UpdatedComponent      = RootComponent;
+  AutoPossessPlayer                       = EAutoReceiveInput::Player0; // Necessary for receiving motion controller events.
+
+  Movement                                = CreateDefaultSubobject<UFloatingPawnMovement>     (TEXT("Movement"));
+  Movement->UpdatedComponent              = RootComponent;
   
-  RotatingComponent                        = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("RotatingComponent0"));
-  RotatingComponent->UpdatedComponent      = RootComponent;
-  RotatingComponent->bRotationInLocalSpace = false;
-  RotatingComponent->PivotTranslation      = FVector::ZeroVector;
-  RotatingComponent->RotationRate          = FRotator::ZeroRotator;
+  RotatingMovement                        = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("RotatingMovement"));
+  RotatingMovement->UpdatedComponent      = RootComponent;
+  RotatingMovement->bRotationInLocalSpace = false;
+  RotatingMovement->PivotTranslation      = FVector::ZeroVector;
+  RotatingMovement->RotationRate          = FRotator::ZeroRotator;
   
-  TranslationDirection                     = RootComponent;
+  LeftMotionController                    = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("LeftMotionController"));
+  LeftMotionController->SetupAttachment    (RootComponent);
+  LeftMotionController->SetTrackingSource  (EControllerHand::Left);
+  LeftMotionController->SetShowDeviceModel (true );
+  LeftMotionController->SetVisibility      (false);
 
-  AutoPossessPlayer                        = EAutoReceiveInput::Player0; // Necessary for receiving motion controller events.
+  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(TranslationDirection->GetForwardVector(), Value);
+  AddMovementInput(Forward->GetForwardVector(), Value);
 }
 void                    AVirtualRealityPawn::OnRight_Implementation     (float Value)
 {
-  AddMovementInput(TranslationDirection->GetRightVector  (), Value);
+  AddMovementInput(Forward->GetRightVector  (), Value);
 }
 void                    AVirtualRealityPawn::OnTurnRate_Implementation  (float Rate )
 {
   if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
   {
-    if (!RotatingComponent->UpdatedComponent || !IDisplayCluster::Get().GetGameMgr() || !IDisplayCluster::Get().GetGameMgr()->GetActiveCamera()) return;
-
-    const FVector CameraLocation = IDisplayCluster::Get().GetGameMgr()->GetActiveCamera()->GetComponentLocation();
-    RotatingComponent->PivotTranslation = RotatingComponent->UpdatedComponent->GetComponentTransform().InverseTransformPositionNoScale(CameraLocation);
-    RotatingComponent->RotationRate     = FRotator(RotatingComponent->RotationRate.Pitch, Rate * BaseTurnRate, 0.0f);
+    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(BaseTurnRate * Rate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
+    AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
   }
 }
 void                    AVirtualRealityPawn::OnLookUpRate_Implementation(float Rate )
 { 
   if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
   {
-    // User-centered projection causes motion sickness on look up interaction hence not implemented.
+    // User-centered projection causes simulation sickness on look up interaction hence not implemented.
   }
   else
   {
-    AddControllerPitchInput(BaseTurnRate * Rate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
+    AddControllerPitchInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
   }
 }
 void                    AVirtualRealityPawn::OnFire_Implementation      (bool Pressed)
@@ -73,44 +81,61 @@ void                    AVirtualRealityPawn::BeginPlay                  ()
 {
   Super::BeginPlay();
   
-	if (!IDisplayCluster::Get().IsModuleInitialized() || !IDisplayCluster::Get().IsAvailable()) return;
-
-  auto IsCluster = (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster);
-  bUseControllerRotationYaw   = !IsCluster;
-  bUseControllerRotationPitch = !IsCluster;
-  bUseControllerRotationRoll  = !IsCluster;
-
+  // 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) return;
+  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       ;
+  }
 
-  ADisplayClusterSettings* Settings = Cast<ADisplayClusterSettings>(SettingsActors[0]);
-  MovementComponent->MaxSpeed       = Settings->MovementMaxSpeed    ;
-  MovementComponent->Acceleration   = Settings->MovementAcceleration;
-  MovementComponent->Deceleration   = Settings->MovementDeceleration;
-  MovementComponent->TurningBoost   = Settings->MovementTurningBoost;
-  BaseTurnRate                      = Settings->RotationSpeed       ;
-  
-  if (UHeadMountedDisplayFunctionLibrary::IsHeadMountedDisplayEnabled())
-  {
-    LeftMotionControllerComponent  = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("LeftMotionControllerComponent"));
-    LeftMotionControllerComponent->SetTrackingSource (EControllerHand::Left);
-    LeftMotionControllerComponent->SetShowDeviceModel(true);
+  if      (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
+  { 
+    // Requires a scene node called flystick in the config.
+    Flystick  = IDisplayCluster::Get().GetGameMgr()->GetNodeById(TEXT("flystick"));
 
-    RightMotionControllerComponent = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("RightMotionControllerComponent"));
-    RightMotionControllerComponent->SetTrackingSource (EControllerHand::Right);
-    RightMotionControllerComponent->SetShowDeviceModel(true);
+    Forward   = Flystick;
+    LeftHand  = Flystick;
+    RightHand = Flystick;
+  }
+  else if (UHeadMountedDisplayFunctionLibrary::IsHeadMountedDisplayEnabled())
+  {
+    LeftMotionController ->SetVisibility(true);
+    RightMotionController->SetVisibility(true);
+    
+    Forward   = LeftMotionController ;
+    LeftHand  = LeftMotionController ;
+    RightHand = RightMotionController;
+  }
+  else
+  {
+    bUseControllerRotationYaw   = true;
+    bUseControllerRotationPitch = true;
+    bUseControllerRotationRoll  = true;
+    
+    Forward   = RootComponent;
+    LeftHand  = RootComponent;
+    RightHand = RootComponent;
   }
 }
 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)
-  {
-    Flystick = IDisplayCluster::Get().GetGameMgr()->GetNodeById(TEXT("flystick")); // Note: Requires a scene node called flystick in the config. Make settable.
-    if (Flystick) 
-      TranslationDirection = 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               ()
@@ -146,5 +171,5 @@ void                    AVirtualRealityPawn::SetupPlayerInputComponent  (UInputC
 }
 UPawnMovementComponent* AVirtualRealityPawn::GetMovementComponent       () const
 {
-  return MovementComponent;
+  return Movement;
 }
diff --git a/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h b/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
index 8cae171605da946cd8072ee4b70acf591a4f7216..0569fdfa0a747634943faa43be1555cac59c2e60 100644
--- a/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
+++ b/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
@@ -23,9 +23,6 @@ public:
   UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnFire      (bool  Pressed);
   UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Pawn") void OnAction    (bool  Pressed, int32 Index);
 
-  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") float                          BaseTurnRate = 45.0f  ;
-  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") UDisplayClusterSceneComponent* Flystick     = nullptr;
-
 protected:
   DECLARE_DELEGATE_OneParam (FFireDelegate  , bool);
   DECLARE_DELEGATE_TwoParams(FActionDelegate, bool, int32);
@@ -36,8 +33,21 @@ protected:
   virtual void                    SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)       override;
   virtual UPawnMovementComponent* GetMovementComponent     ()                                      const override;
   
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) UFloatingPawnMovement*      MovementComponent              = nullptr;
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) URotatingMovementComponent* RotatingComponent              = nullptr;
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) UMotionControllerComponent* LeftMotionControllerComponent  = nullptr;
-  UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) UMotionControllerComponent* RightMotionControllerComponent = nullptr;
+  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;
 };