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(); };