diff --git a/Source/DisplayClusterExtensions/Private/VRPawnMovement.cpp b/Source/DisplayClusterExtensions/Private/VRPawnMovement.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..37b75ccf3a9cdd10b80a17a41866d1a20352c0f1
--- /dev/null
+++ b/Source/DisplayClusterExtensions/Private/VRPawnMovement.cpp
@@ -0,0 +1,192 @@
+
+#include "VRPawnMovement.h"
+#include "DrawDebugHelpers.h"
+
+UVRPawnMovement::UVRPawnMovement(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
+{
+ CapsuleColliderComponent = CreateDefaultSubobject<UCapsuleComponent>(TEXT("CapsuleCollider"));
+ CapsuleColliderComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
+ CapsuleColliderComponent->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
+ CapsuleColliderComponent->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block);
+ CapsuleColliderComponent->SetCapsuleSize(40.0f, 96.0f);
+}
+
+void UVRPawnMovement::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction){
+
+ SetCapsuleColliderToUserSize();
+
+ FVector PositionChange = GetPendingInputVector();
+
+ if (NavigationMode == EVRNavigationModes::Walk)
+ {
+ PositionChange.Z = 0.0f;
+ ConsumeInputVector();
+ AddInputVector(PositionChange);
+ }
+
+ if(NavigationMode == EVRNavigationModes::Fly || NavigationMode == EVRNavigationModes::Walk)
+ {
+ MoveByGravityOrStepUp(DeltaTime);
+ CheckForPhysWalkingCollision();
+
+ if(CheckForVirtualMovCollision(PositionChange, DeltaTime))
+ {
+ ConsumeInputVector();
+ }
+ }
+
+ if(NavigationMode == EVRNavigationModes::None)
+ {
+ ConsumeInputVector();
+ }
+
+ Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
+
+ LastCameraPosition = CameraComponent->GetComponentLocation();
+}
+
+bool UVRPawnMovement::CheckForVirtualMovCollision(FVector PositionChange, float DeltaTime)
+{
+ FVector ProbePosition = PositionChange.GetSafeNormal() * GetMaxSpeed() * DeltaTime;
+ FHitResult FHitResultVR;
+ CapsuleColliderComponent->AddWorldOffset(ProbePosition, true, &FHitResultVR);
+ if (FVector::Distance(FHitResultVR.Location, CapsuleColliderComponent->GetComponentLocation()) < CapsuleColliderComponent->GetScaledCapsuleRadius())
+ {
+ return true;
+ }
+ return false;
+}
+
+void UVRPawnMovement::SetCameraComponent(UCameraComponent* NewCameraComponent)
+{
+ CameraComponent = NewCameraComponent;
+ CapsuleColliderComponent->SetupAttachment(CameraComponent);
+}
+
+
+void UVRPawnMovement::SetCapsuleColliderToUserSize()
+{
+ float CharachterSize = abs(UpdatedComponent->GetComponentLocation().Z - CameraComponent->GetComponentLocation().Z);
+
+ if (CharachterSize > MaxStepHeight)
+ {
+ float ColliderHeight = CharachterSize - MaxStepHeight;
+ float ColliderHalfHeight = ColliderHeight / 2.0f;
+ float ColliderRadius = 40.0f;
+ if (ColliderHalfHeight <= ColliderRadius)
+ {//Make the collider to a Sphere
+ CapsuleColliderComponent->SetCapsuleSize(ColliderHalfHeight, ColliderHalfHeight);
+ }
+ else
+ {//Make the collider to a Capsule
+ CapsuleColliderComponent->SetCapsuleSize(ColliderRadius, ColliderHalfHeight);
+ }
+
+ CapsuleColliderComponent->SetWorldLocation(CameraComponent->GetComponentLocation());
+ CapsuleColliderComponent->AddWorldOffset(FVector(0, 0, -ColliderHalfHeight));
+ CapsuleColliderComponent->SetWorldRotation(FRotator(0, 0, 1));
+ }
+ else
+ {
+ CapsuleColliderComponent->SetWorldLocation(CameraComponent->GetComponentLocation());
+ CapsuleColliderComponent->SetWorldRotation(FRotator(0, 0, 1));
+ }
+}
+
+void UVRPawnMovement::CheckForPhysWalkingCollision()
+{
+ FVector CurrentCameraPosition = CameraComponent->GetComponentLocation();
+ FVector Direction = CurrentCameraPosition - LastCameraPosition;
+ FHitResult FHitResultPhys;
+ CapsuleColliderComponent->AddWorldOffset(Direction, true, &FHitResultPhys);
+
+ if (FHitResultPhys.bBlockingHit)
+ {
+ UpdatedComponent->AddLocalOffset(FHitResultPhys.Normal*FHitResultPhys.PenetrationDepth);
+ }
+}
+
+void UVRPawnMovement::MoveByGravityOrStepUp(float DeltaSeconds)
+{
+ FVector StartLineTraceUnderCollider = CapsuleColliderComponent->GetComponentLocation();
+ StartLineTraceUnderCollider.Z -= CapsuleColliderComponent->GetScaledCapsuleHalfHeight();
+ FHitResult HitDetailsMultiLineTrace = CreateMultiLineTrace(FVector(0, 0, -1), StartLineTraceUnderCollider, CapsuleColliderComponent->GetScaledCapsuleRadius() / 4.0f, false);
+ float DistanceDifference = abs(MaxStepHeight - HitDetailsMultiLineTrace.Distance);
+ //Going up (in Fly and Walk Mode)
+ if ((HitDetailsMultiLineTrace.bBlockingHit && HitDetailsMultiLineTrace.Distance < MaxStepHeight))
+ {
+ ShiftVertically(DistanceDifference, UpSteppingAcceleration, DeltaSeconds, 1);
+ }
+ //Gravity (only in Walk Mode)
+ else if (NavigationMode==EVRNavigationModes::Walk && ((HitDetailsMultiLineTrace.bBlockingHit && HitDetailsMultiLineTrace.Distance > MaxStepHeight) || (HitDetailsMultiLineTrace.Actor == nullptr && HitDetailsMultiLineTrace.Distance != -1.0f)))
+ {
+ ShiftVertically(DistanceDifference, GravityAcceleration, DeltaSeconds, -1);
+ }
+}
+
+void UVRPawnMovement::ShiftVertically(float DiffernceDistance, float VerticalAcceleration, float DeltaSeconds, int Direction)
+{
+ VerticalSpeed += VerticalAcceleration * DeltaSeconds;
+ if (VerticalSpeed*DeltaSeconds < DiffernceDistance)
+ {
+ UpdatedComponent->AddLocalOffset(FVector(0.f, 0.f, Direction * VerticalSpeed * DeltaSeconds));
+ }
+ else
+ {
+ UpdatedComponent->AddLocalOffset(FVector(0.f, 0.f, Direction * DiffernceDistance));
+ VerticalSpeed = 0;
+ }
+}
+
+FHitResult UVRPawnMovement::CreateLineTrace(FVector Direction, const FVector Start, bool Visibility)
+{
+ //Re-initialize hit info
+ FHitResult HitDetails = FHitResult(ForceInit);
+
+ FVector End = ((Direction * 1000.f) + Start);
+ // additional trace parameters
+ FCollisionQueryParams TraceParams(FName(TEXT("InteractTrace")), true, NULL);
+ TraceParams.bTraceComplex = true; //to use complex collision on whatever we interact with to provide better precision.
+ TraceParams.bReturnPhysicalMaterial = true; //to provide details about the physical material, if one exists on the thing we hit, to come back in our hit result.
+
+ if (Visibility)
+ DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1, 0, 1);
+
+ if (GetWorld()->LineTraceSingleByChannel(HitDetails, Start, End, ECC_Visibility, TraceParams))
+ {
+ if (HitDetails.bBlockingHit)
+ {
+ }
+ }
+ return HitDetails;
+}
+
+FHitResult UVRPawnMovement::CreateMultiLineTrace(FVector Direction, const FVector Start, float Radius, bool Visibility)
+{
+ TArray<FVector> StartVectors;
+ TArray<FHitResult> OutHits;
+ FHitResult HitDetailsMultiLineTrace;
+ HitDetailsMultiLineTrace.Distance = -1.0f;//(Distance=-1) not existing, but to know if this Variable not Initialized(when all Traces not compatible)
+
+ StartVectors.Add(Start); //LineTraceCenter
+ StartVectors.Add(Start + FVector(0, -Radius, 0)); //LineTraceLeft
+ StartVectors.Add(Start + FVector(0, +Radius, 0)); //LineTraceRight
+ StartVectors.Add(Start + FVector(+Radius, 0, 0)); //LineTraceFront
+ StartVectors.Add(Start + FVector(-Radius, 0, 0)); //LineTraceBehind
+
+ bool IsBlockingHitAndSameActor = true;
+ bool IsAllNothingHiting = true;
+ // loop through TArray
+ for (FVector& Vector : StartVectors)
+ {
+ FHitResult OutHit = CreateLineTrace(Direction, Vector, Visibility);
+ OutHits.Add(OutHit);
+ IsBlockingHitAndSameActor &= (OutHit.Actor == OutHits[0].Actor); //If all Hiting the same Object, then you are (going up/down) or (walking)
+ IsAllNothingHiting &= (OutHit.Actor == nullptr); //If all Hiting nothing, then you are falling
+ }
+
+ if (IsBlockingHitAndSameActor || IsAllNothingHiting)
+ HitDetailsMultiLineTrace = OutHits[0];
+
+ return HitDetailsMultiLineTrace;
+}
\ No newline at end of file
diff --git a/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp b/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
index de17d478c5ac6bc9be9124d845fdc3f56b7aa960..57750819a5c2afac0f930263dd8e720201bed309 100644
--- a/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
+++ b/Source/DisplayClusterExtensions/Private/VirtualRealityPawn.cpp
@@ -27,8 +27,9 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial
AutoPossessPlayer = EAutoReceiveInput::Player0; // Necessary for receiving motion controller events.
- Movement = CreateDefaultSubobject<UFloatingPawnMovement>(TEXT("Movement"));
- Movement->UpdatedComponent = RootComponent;
+ VRMovement = CreateDefaultSubobject<UVRPawnMovement>(TEXT("WalkingMovement"));
+ VRMovement->SetUpdatedComponent(RootComponent);
+ VRMovement->SetCameraComponent(CameraComponent);
RotatingMovement = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("RotatingMovement"));
RotatingMovement->UpdatedComponent = RootComponent;
@@ -55,13 +56,6 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial
HmdRightMotionController->SetShowDeviceModel(true);
HmdRightMotionController->SetVisibility(false);
- CapsuleColliderComponent = CreateDefaultSubobject<UCapsuleComponent>(TEXT("CapsuleCollider"));
- CapsuleColliderComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
- CapsuleColliderComponent->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
- CapsuleColliderComponent->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block);
- CapsuleColliderComponent->SetupAttachment(CameraComponent);
- CapsuleColliderComponent->SetCapsuleSize(40.0f, 96.0f);
-
HmdTracker1 = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdTracker1"));
HmdTracker1->SetupAttachment(RootComponent);
HmdTracker1->SetTrackingSource(EControllerHand::Special_1);
@@ -79,7 +73,7 @@ void AVirtualRealityPawn::OnForward_Implementation(float Value)
{
if (RightHand)
{
- HandleMovementInput(Value, RightHand->GetForwardVector());
+ AddMovementInput(RightHand->GetForwardVector(), Value);
}
}
@@ -87,7 +81,7 @@ void AVirtualRealityPawn::OnRight_Implementation(float Value)
{
if (RightHand)
{
- HandleMovementInput(Value, RightHand->GetRightVector());
+ AddMovementInput(RightHand->GetRightVector(), Value);
}
}
@@ -118,11 +112,6 @@ void AVirtualRealityPawn::SetBaseTurnRate(float Value)
BaseTurnRate = Value;
}
-UFloatingPawnMovement* AVirtualRealityPawn::GetFloatingPawnMovement()
-{
- return Movement;
-}
-
URotatingMovementComponent* AVirtualRealityPawn::GetRotatingMovementComponent()
{
return RotatingMovement;
@@ -221,10 +210,10 @@ void AVirtualRealityPawn::BeginPlay()
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;
+ VRMovement->MaxSpeed = Settings->MovementMaxSpeed;
+ VRMovement->Acceleration = Settings->MovementAcceleration;
+ VRMovement->Deceleration = Settings->MovementDeceleration;
+ VRMovement->TurningBoost = Settings->MovementTurningBoost;
BaseTurnRate = Settings->RotationSpeed;
}
@@ -288,8 +277,6 @@ void AVirtualRealityPawn::BeginPlay()
CollisionComponent->SetCollisionProfileName(FName("NoCollision"));
CollisionComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
-
- LastCameraPosition = CameraComponent->GetComponentLocation();
}
void AVirtualRealityPawn::EndPlay(const EEndPlayReason::Type EndPlayReason)
@@ -306,14 +293,6 @@ void AVirtualRealityPawn::EndPlay(const EEndPlayReason::Type EndPlayReason)
void AVirtualRealityPawn::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
- //if the walking-mode is activated
- if (NavigationMode == EVRNavigationModes::nav_mode_walk)
- {
- DeltaTime = DeltaSeconds;
- SetCapsuleColliderCharacterSizeVR();
- MoveByGravityOrStepUp(DeltaSeconds);
- CheckForPhysWalkingCollision();
- }
// if an actor is grabbed and a behavior is defined move move him accordingly
if (GrabbedActor != nullptr)
@@ -333,8 +312,6 @@ void AVirtualRealityPawn::Tick(float DeltaSeconds)
//Flystick might not be available at start, hence is checked every frame.
InitRoomMountedComponentReferences();
-
- LastCameraPosition = CameraComponent->GetComponentLocation();
}
void AVirtualRealityPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
@@ -440,111 +417,7 @@ FTwoVectors AVirtualRealityPawn::GetHandRay(float Length)
UPawnMovementComponent* AVirtualRealityPawn::GetMovementComponent() const
{
- return Movement;
-}
-
-void AVirtualRealityPawn::SetCapsuleColliderCharacterSizeVR()
-{
- float CharachterSize = abs(RootComponent->GetComponentLocation().Z - CameraComponent->GetComponentLocation().Z);
-
- if (CharachterSize > MaxStepHeight)
- {
- float ColliderHeight = CharachterSize - MaxStepHeight;
- float ColliderHalfHeight = ColliderHeight / 2.0f;
- float ColliderRadius = 40.0f;
- if (ColliderHalfHeight <= ColliderRadius)
- {//Make the collider to a Sphere
- CapsuleColliderComponent->SetCapsuleSize(ColliderHalfHeight, ColliderHalfHeight);
- }
- else
- {//Make the collider to a Capsule
- CapsuleColliderComponent->SetCapsuleSize(ColliderRadius, ColliderHalfHeight);
- }
-
- CapsuleColliderComponent->SetWorldLocation(CameraComponent->GetComponentLocation());
- CapsuleColliderComponent->AddWorldOffset(FVector(0, 0, -ColliderHalfHeight));
- CapsuleColliderComponent->SetWorldRotation(FRotator(0, 0, 1));
- }
- else
- {
- CapsuleColliderComponent->SetWorldLocation(CameraComponent->GetComponentLocation());
- CapsuleColliderComponent->SetWorldRotation(FRotator(0, 0, 1));
- }
-}
-
-void AVirtualRealityPawn::CheckForPhysWalkingCollision()
-{
- FVector CurrentCameraPosition = CameraComponent->GetComponentLocation();
- FVector Direction = CurrentCameraPosition - LastCameraPosition;
- FHitResult FHitResultPhys;
- CapsuleColliderComponent->AddWorldOffset(Direction, true, &FHitResultPhys);
-
- if (FHitResultPhys.bBlockingHit)
- {
- RootComponent->AddLocalOffset(FHitResultPhys.Normal*FHitResultPhys.PenetrationDepth);
- }
-}
-
-void AVirtualRealityPawn::HandleMovementInput(float Value, FVector Direction)
-{
- if (NavigationMode == EVRNavigationModes::nav_mode_walk)
- {
- VRWalkingMode(Value, Direction);
- }
- else if (NavigationMode == EVRNavigationModes::nav_mode_fly)
- {
- VRFlyingMode(Value, Direction);
- }
-}
-
-void AVirtualRealityPawn::VRWalkingMode(float Value, FVector Direction)
-{
- Direction.Z = 0.0f;//walking
- FVector End = (Direction * GetFloatingPawnMovement()->GetMaxSpeed());
- FHitResult FHitResultVR;
- CapsuleColliderComponent->AddWorldOffset(End* DeltaTime*Value, true, &FHitResultVR);
-
- if (FVector::Distance(FHitResultVR.Location, CapsuleColliderComponent->GetComponentLocation()) > CapsuleColliderComponent->GetScaledCapsuleRadius())
- {
- AddMovementInput(Direction, Value);
- }
-}
-
-void AVirtualRealityPawn::VRFlyingMode(float Value, FVector Direction)
-{
- AddMovementInput(Direction, Value);
-}
-
-void AVirtualRealityPawn::MoveByGravityOrStepUp(float DeltaSeconds)
-{
- FVector StartLineTraceUnderCollider = CapsuleColliderComponent->GetComponentLocation();
- StartLineTraceUnderCollider.Z -= CapsuleColliderComponent->GetScaledCapsuleHalfHeight();
- FHitResult HitDetailsMultiLineTrace = CreateMultiLineTrace(FVector(0, 0, -1), StartLineTraceUnderCollider, CapsuleColliderComponent->GetScaledCapsuleRadius() / 4.0f, false);
- float DiffernceDistance = abs(MaxStepHeight - HitDetailsMultiLineTrace.Distance);
- //Going up
- if ((HitDetailsMultiLineTrace.bBlockingHit && HitDetailsMultiLineTrace.Distance < MaxStepHeight))
- {
- ShiftVertically(DiffernceDistance, UpSteppingAcceleration, DeltaSeconds, 1);
- }
- //Falling, Gravity, Going down
- else if ((HitDetailsMultiLineTrace.bBlockingHit && HitDetailsMultiLineTrace.Distance > MaxStepHeight) || (HitDetailsMultiLineTrace.Actor == nullptr && HitDetailsMultiLineTrace.Distance != -1.0f))
- {
- ShiftVertically(DiffernceDistance, GravityAcceleration, DeltaSeconds, -1);
- }
-}
-
-void AVirtualRealityPawn::ShiftVertically(float DiffernceDistance, float Acceleration, float DeltaSeconds, int Direction)
-{
- VerticalSpeed += Acceleration * DeltaSeconds;
- if (VerticalSpeed*DeltaSeconds < DiffernceDistance)
- {
- RootComponent->AddLocalOffset(FVector(0.f, 0.f, Direction * VerticalSpeed * DeltaSeconds));
- }
- else
- {
- RootComponent->AddLocalOffset(FVector(0.f, 0.f, Direction * DiffernceDistance));
- VerticalSpeed = 0;
- }
+ return VRMovement;
}
void AVirtualRealityPawn::InitRoomMountedComponentReferences()
@@ -582,56 +455,7 @@ void AVirtualRealityPawn::InitRoomMountedComponentReferences()
}
}
-
-FHitResult AVirtualRealityPawn::CreateLineTrace(FVector Direction, const FVector Start, bool Visibility)
-{
- //Re-initialize hit info
- FHitResult HitDetails = FHitResult(ForceInit);
-
- FVector End = ((Direction * 1000.f) + Start);
- // additional trace parameters
- FCollisionQueryParams TraceParams(FName(TEXT("InteractTrace")), true, NULL);
- TraceParams.bTraceComplex = true; //to use complex collision on whatever we interact with to provide better precision.
- TraceParams.bReturnPhysicalMaterial = true; //to provide details about the physical material, if one exists on the thing we hit, to come back in our hit result.
-
- if (Visibility)
- DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1, 0, 1);
-
- if (GetWorld()->LineTraceSingleByChannel(HitDetails, Start, End, ECC_Visibility, TraceParams))
- {
- if (HitDetails.bBlockingHit)
- {
- }
- }
- return HitDetails;
-}
-
-FHitResult AVirtualRealityPawn::CreateMultiLineTrace(FVector Direction, const FVector Start, float Radius, bool Visibility)
+void AVirtualRealityPawn::SetNavigationMode(EVRNavigationModes Mode)
{
- TArray<FVector> StartVectors;
- TArray<FHitResult> OutHits;
- FHitResult HitDetailsMultiLineTrace;
- HitDetailsMultiLineTrace.Distance = -1.0f;//(Distance=-1) not existing, but to know if this Variable not Initialized(when all Traces not compatible)
-
- StartVectors.Add(Start); //LineTraceCenter
- StartVectors.Add(Start + FVector(0, -Radius, 0)); //LineTraceLeft
- StartVectors.Add(Start + FVector(0, +Radius, 0)); //LineTraceRight
- StartVectors.Add(Start + FVector(+Radius, 0, 0)); //LineTraceFront
- StartVectors.Add(Start + FVector(-Radius, 0, 0)); //LineTraceBehind
-
- bool IsBlockingHitAndSameActor = true;
- bool IsAllNothingHiting = true;
- // loop through TArray
- for (FVector& Vector : StartVectors)
- {
- FHitResult OutHit = CreateLineTrace(Direction, Vector, Visibility);
- OutHits.Add(OutHit);
- IsBlockingHitAndSameActor &= (OutHit.Actor == OutHits[0].Actor); //If all Hiting the same Object, then you are (going up/down) or (walking)
- IsAllNothingHiting &= (OutHit.Actor == nullptr); //If all Hiting nothing, then you are falling
- }
-
- if (IsBlockingHitAndSameActor || IsAllNothingHiting)
- HitDetailsMultiLineTrace = OutHits[0];
-
- return HitDetailsMultiLineTrace;
+ VRMovement->NavigationMode = Mode;
}
diff --git a/Source/DisplayClusterExtensions/Public/VRPawnMovement.h b/Source/DisplayClusterExtensions/Public/VRPawnMovement.h
new file mode 100644
index 0000000000000000000000000000000000000000..20a6f4b6707cd7a8ec60116f4fb0386d9fc017a4
--- /dev/null
+++ b/Source/DisplayClusterExtensions/Public/VRPawnMovement.h
@@ -0,0 +1,70 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "GameFramework/FloatingPawnMovement.h"
+#include "Components/CapsuleComponent.h"
+#include "Camera/CameraComponent.h"
+
+#include "VRPawnMovement.generated.h"
+
+/*
+ * This Movement component is needed since in VR not only the pawn itself (UpdatedComponent) is moved but also the
+ * user herself can walk and thereby move the CameraComponent, which can also lead to collisions or e.g. going up steps
+ *
+ * The four modes are:
+ * None: No controller movement is applied and no corrections regarding steps or collisions with walls are done
+ * Ghost: The same as above but now the Inputs can be used for unconstrained flying (also through objects)
+ * Fly: The user can fly but not through walls etc. When the user walks against a wall the scene is moved with her to avoid walking through
+ * The user can also walk up stairs with a maximum step height of MaxStepHeight
+ * Walk: Additionally to Fly now gravity keeps the user on the floor
+ */
+
+UENUM(BlueprintType)
+enum class EVRNavigationModes : uint8
+{
+ None UMETA(DisplayName = "None (no controller movement)"),
+ Ghost UMETA(DisplayName = "Ghost (flying, also through walls)"),
+ Fly UMETA(DisplayName = "Fly (prohibiting collisions)"),
+ Walk UMETA(DisplayName = "Walk (gravity and prohibiting collisions)")
+};
+
+UCLASS()
+class DISPLAYCLUSTEREXTENSIONS_API UVRPawnMovement : public UFloatingPawnMovement
+{
+ GENERATED_UCLASS_BODY()
+
+public:
+
+ virtual void TickComponent(float DeltaTime, enum ELevelTick TickType,
+ FActorComponentTickFunction* ThisTickFunction) override;
+
+ void SetCameraComponent(UCameraComponent* NewCameraComponent);
+
+ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement")
+ EVRNavigationModes NavigationMode = EVRNavigationModes::Walk;
+
+ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement")
+ float MaxStepHeight = 40.0f;
+
+ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement")
+ float GravityAcceleration = 981.0f;
+
+ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement")
+ float UpSteppingAcceleration = 500.0f;
+
+private:
+ FHitResult CreateLineTrace(FVector Direction, const FVector Start, bool Visibility);
+ FHitResult CreateMultiLineTrace(FVector Direction, const FVector Start, float Radius, bool Visibility);
+ void SetCapsuleColliderToUserSize();
+ void CheckForPhysWalkingCollision();
+ bool CheckForVirtualMovCollision(FVector PositionChange, float DeltaTime);
+ void MoveByGravityOrStepUp(float DeltaSeconds);
+ void ShiftVertically(float DiffernceDistance, float VerticalAcceleration, float DeltaSeconds, int Direction);
+ //(direction = Down = -1), (direction = Up = 1)
+
+ UPROPERTY() UCapsuleComponent* CapsuleColliderComponent = nullptr;
+ UPROPERTY() UCameraComponent* CameraComponent = nullptr;
+
+ float VerticalSpeed = 0.0f;
+ FVector LastCameraPosition;
+};
diff --git a/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h b/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
index 0570e8aa290c2325b927bca9d036108b0df95741..b02f183320a14b199290438a8f3d4a21f50389ee 100644
--- a/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
+++ b/Source/DisplayClusterExtensions/Public/VirtualRealityPawn.h
@@ -6,20 +6,13 @@
#include "DisplayClusterPawn.h"
#include "DisplayClusterSceneComponent.h"
#include "Components/CapsuleComponent.h"
-#include "GameFramework/FloatingPawnMovement.h"
-#include "GameFramework/PawnMovementComponent.h"
+#include "VRPawnMovement.h"
#include "GameFramework/RotatingMovementComponent.h"
#include "MotionControllerComponent.h"
#include "VirtualRealityPawn.generated.h"
-UENUM(BlueprintType)
-enum class EVRNavigationModes : uint8
-{
- nav_mode_none UMETA(DisplayName = "Navigation Mode None"),
- nav_mode_walk UMETA(DisplayName = "Navigation Mode Walk"),
- nav_mode_fly UMETA(DisplayName = "Navigation Mode Fly")
-};
+
UENUM(BlueprintType)
enum class EAttachementType : uint8
@@ -44,7 +37,6 @@ public:
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
@@ -63,6 +55,8 @@ public:
UFUNCTION(Category = "Pawn") USceneComponent* GetTrackingOriginComponent();
+ UFUNCTION(Category = "Pawn") void SetNavigationMode(EVRNavigationModes Mode);
+
private:
UFUNCTION(Category = "Pawn") USceneComponent* GetCaveCenterComponent();
UFUNCTION(Category = "Pawn") USceneComponent* GetShutterGlassesComponent();
@@ -70,9 +64,6 @@ private:
UFUNCTION(Category = "Pawn") void HandlePhysicsAndAttachActor(AActor* HitActor);
public:
- UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EVRNavigationModes NavigationMode = EVRNavigationModes::nav_mode_fly;
-
- UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") float MaxStepHeight = 40.0f;
//Execute specified console command on all nDisplayCluster Nodes
UFUNCTION(Exec, BlueprintCallable, Category = "DisplayCluster") static void ClusterExecute(const FString& Command);
private:
@@ -87,7 +78,7 @@ protected:
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")) UVRPawnMovement* VRMovement = 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.
@@ -131,22 +122,6 @@ protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EAttachementType AttachRightHandInCAVE = EAttachementType::AT_FLYSTICK;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EAttachementType AttachLeftHandInCAVE = EAttachementType::AT_NONE;
- UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) UCapsuleComponent* CapsuleColliderComponent = nullptr;
private:
- float DeltaTime = 0.0f;
- float VerticalSpeed = 0.0f;
- UPROPERTY() float GravityAcceleration = 981.0f;
- UPROPERTY() float UpSteppingAcceleration = 500.0f;
- FVector LastCameraPosition;
-
- FHitResult CreateLineTrace(FVector Direction, const FVector Start, bool Visibility);
- FHitResult CreateMultiLineTrace(FVector Direction, const FVector Start, float Radius, bool Visibility);
- void SetCapsuleColliderCharacterSizeVR();
- void CheckForPhysWalkingCollision();
- void HandleMovementInput(float Value, FVector Direction);
- void VRWalkingMode(float Value, FVector Direction);
- void VRFlyingMode(float Value, FVector Direction);
- void MoveByGravityOrStepUp(float DeltaSeconds);
- void ShiftVertically(float DiffernceDistance, float Acceleration, float DeltaSeconds, int Direction);//(direction = Down = -1), (direction = Up = 1)
void InitRoomMountedComponentReferences();
};