Skip to content
Snippets Groups Projects
Commit b4e2c84e authored by Simon Oehrl's avatar Simon Oehrl
Browse files

Merge branch 'feature/walking_behavior' into 'develop'

Feature/walking behavior

See merge request VR-Group/unreal-development/ndisplayextensions!22
parents b04105bb eeb39ed4
No related branches found
No related tags found
No related merge requests found
#include "VirtualRealityPawn.h" #include "VirtualRealityPawn.h"
#include "Camera/CameraComponent.h" #include "Camera/CameraComponent.h"
#include "Cluster/IDisplayClusterClusterManager.h"
#include "Engine/Engine.h" #include "Engine/Engine.h"
#include "Engine/World.h" #include "Engine/World.h"
#include "Game/IDisplayClusterGameManager.h" #include "Game/IDisplayClusterGameManager.h"
...@@ -10,12 +9,16 @@ ...@@ -10,12 +9,16 @@
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "DisplayClusterSettings.h" #include "DisplayClusterSettings.h"
#include "IDisplayCluster.h" #include "IDisplayCluster.h"
#include "Components/SphereComponent.h"
#include "DrawDebugHelpers.h"
#include "Math/Vector.h"
#include "VirtualRealityUtilities.h" #include "VirtualRealityUtilities.h"
#include "GrabbingBehaviorComponent.h" #include "GrabbingBehaviorComponent.h"
#include "Grabable.h" #include "Grabable.h"
#include "Clickable.h" #include "Clickable.h"
AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{ {
bUseControllerRotationYaw = true; bUseControllerRotationYaw = true;
...@@ -52,6 +55,13 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial ...@@ -52,6 +55,13 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial
HmdRightMotionController->SetShowDeviceModel(true); HmdRightMotionController->SetShowDeviceModel(true);
HmdRightMotionController->SetVisibility(false); 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 = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("HmdTracker1"));
HmdTracker1->SetupAttachment(RootComponent); HmdTracker1->SetupAttachment(RootComponent);
HmdTracker1->SetTrackingSource(EControllerHand::Special_1); HmdTracker1->SetTrackingSource(EControllerHand::Special_1);
...@@ -67,36 +77,22 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial ...@@ -67,36 +77,22 @@ AVirtualRealityPawn::AVirtualRealityPawn(const FObjectInitializer& ObjectInitial
void AVirtualRealityPawn::OnForward_Implementation(float Value) void AVirtualRealityPawn::OnForward_Implementation(float Value)
{ {
// Check if this function triggers correctly on ROLV. if (RightHand)
if (RightHand && (NavigationMode == EVRNavigationModes::nav_mode_fly || UVirtualRealityUtilities::IsDesktopMode() || UVirtualRealityUtilities::IsHeadMountedMode()))
{ {
AddMovementInput(RightHand->GetForwardVector(), Value); HandleMovementInput(Value, RightHand->GetForwardVector());
} }
} }
void AVirtualRealityPawn::OnRight_Implementation(float Value) void AVirtualRealityPawn::OnRight_Implementation(float Value)
{ {
if (RightHand && (NavigationMode == EVRNavigationModes::nav_mode_fly || UVirtualRealityUtilities::IsDesktopMode() || UVirtualRealityUtilities::IsHeadMountedMode())) if (RightHand)
{ {
AddMovementInput(RightHand->GetRightVector(), Value); HandleMovementInput(Value, RightHand->GetRightVector());
} }
} }
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);
//}
AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation); AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
} }
...@@ -289,6 +285,11 @@ void AVirtualRealityPawn::BeginPlay() ...@@ -289,6 +285,11 @@ void AVirtualRealityPawn::BeginPlay()
ClusterEventListenerDelegate = FOnClusterEventListener::CreateUObject(this, &AVirtualRealityPawn::HandleClusterEvent); ClusterEventListenerDelegate = FOnClusterEventListener::CreateUObject(this, &AVirtualRealityPawn::HandleClusterEvent);
ClusterManager->AddClusterEventListener(ClusterEventListenerDelegate); ClusterManager->AddClusterEventListener(ClusterEventListenerDelegate);
} }
CollisionComponent->SetCollisionProfileName(FName("NoCollision"));
CollisionComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
LastCameraPosition = CameraComponent->GetComponentLocation();
} }
void AVirtualRealityPawn::EndPlay(const EEndPlayReason::Type EndPlayReason) void AVirtualRealityPawn::EndPlay(const EEndPlayReason::Type EndPlayReason)
...@@ -305,6 +306,14 @@ void AVirtualRealityPawn::EndPlay(const EEndPlayReason::Type EndPlayReason) ...@@ -305,6 +306,14 @@ void AVirtualRealityPawn::EndPlay(const EEndPlayReason::Type EndPlayReason)
void AVirtualRealityPawn::Tick(float DeltaSeconds) void AVirtualRealityPawn::Tick(float DeltaSeconds)
{ {
Super::Tick(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 an actor is grabbed and a behavior is defined move move him accordingly
if (GrabbedActor != nullptr) if (GrabbedActor != nullptr)
...@@ -324,6 +333,8 @@ void AVirtualRealityPawn::Tick(float DeltaSeconds) ...@@ -324,6 +333,8 @@ void AVirtualRealityPawn::Tick(float DeltaSeconds)
//Flystick might not be available at start, hence is checked every frame. //Flystick might not be available at start, hence is checked every frame.
InitRoomMountedComponentReferences(); InitRoomMountedComponentReferences();
LastCameraPosition = CameraComponent->GetComponentLocation();
} }
void AVirtualRealityPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) void AVirtualRealityPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
...@@ -432,6 +443,110 @@ UPawnMovementComponent* AVirtualRealityPawn::GetMovementComponent() const ...@@ -432,6 +443,110 @@ UPawnMovementComponent* AVirtualRealityPawn::GetMovementComponent() const
return Movement; 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;
}
}
void AVirtualRealityPawn::InitRoomMountedComponentReferences() void AVirtualRealityPawn::InitRoomMountedComponentReferences()
{ {
if (!UVirtualRealityUtilities::IsRoomMountedMode()) return; if (!UVirtualRealityUtilities::IsRoomMountedMode()) return;
...@@ -466,3 +581,57 @@ void AVirtualRealityPawn::InitRoomMountedComponentReferences() ...@@ -466,3 +581,57 @@ void AVirtualRealityPawn::InitRoomMountedComponentReferences()
RightHand->AttachToComponent(RightHandTarget, FAttachmentTransformRules::SnapToTargetIncludingScale); RightHand->AttachToComponent(RightHandTarget, FAttachmentTransformRules::SnapToTargetIncludingScale);
} }
} }
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)
{
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;
}
...@@ -5,9 +5,11 @@ ...@@ -5,9 +5,11 @@
#include "Cluster/IDisplayClusterClusterManager.h" #include "Cluster/IDisplayClusterClusterManager.h"
#include "DisplayClusterPawn.h" #include "DisplayClusterPawn.h"
#include "DisplayClusterSceneComponent.h" #include "DisplayClusterSceneComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/FloatingPawnMovement.h" #include "GameFramework/FloatingPawnMovement.h"
#include "GameFramework/PawnMovementComponent.h" #include "GameFramework/PawnMovementComponent.h"
#include "GameFramework/RotatingMovementComponent.h" #include "GameFramework/RotatingMovementComponent.h"
#include "MotionControllerComponent.h" #include "MotionControllerComponent.h"
#include "VirtualRealityPawn.generated.h" #include "VirtualRealityPawn.generated.h"
...@@ -15,6 +17,7 @@ UENUM(BlueprintType) ...@@ -15,6 +17,7 @@ UENUM(BlueprintType)
enum class EVRNavigationModes : uint8 enum class EVRNavigationModes : uint8
{ {
nav_mode_none UMETA(DisplayName = "Navigation Mode None"), nav_mode_none UMETA(DisplayName = "Navigation Mode None"),
nav_mode_walk UMETA(DisplayName = "Navigation Mode Walk"),
nav_mode_fly UMETA(DisplayName = "Navigation Mode Fly") nav_mode_fly UMETA(DisplayName = "Navigation Mode Fly")
}; };
...@@ -69,14 +72,14 @@ private: ...@@ -69,14 +72,14 @@ private:
public: public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EVRNavigationModes NavigationMode = EVRNavigationModes::nav_mode_fly; 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 //Execute specified console command on all nDisplayCluster Nodes
UFUNCTION(Exec, BlueprintCallable, Category = "DisplayCluster") static void ClusterExecute(const FString& Command); UFUNCTION(Exec, BlueprintCallable, Category = "DisplayCluster") static void ClusterExecute(const FString& Command);
private: private:
FOnClusterEventListener ClusterEventListenerDelegate; FOnClusterEventListener ClusterEventListenerDelegate;
UFUNCTION() void HandleClusterEvent(const FDisplayClusterClusterEvent& Event); UFUNCTION() void HandleClusterEvent(const FDisplayClusterClusterEvent& Event);
protected: protected:
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void Tick(float DeltaSeconds) override; virtual void Tick(float DeltaSeconds) override;
...@@ -128,6 +131,22 @@ protected: ...@@ -128,6 +131,22 @@ protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EAttachementType AttachRightHandInCAVE = EAttachementType::AT_FLYSTICK; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EAttachementType AttachRightHandInCAVE = EAttachementType::AT_FLYSTICK;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EAttachementType AttachLeftHandInCAVE = EAttachementType::AT_NONE; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pawn") EAttachementType AttachLeftHandInCAVE = EAttachementType::AT_NONE;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn", meta = (AllowPrivateAccess = "true")) UCapsuleComponent* CapsuleColliderComponent = nullptr;
private: 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(); void InitRoomMountedComponentReferences();
}; };
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment