Floor detection now works for all gravity directions

This commit is contained in:
Kevin Poretti 2023-01-05 16:27:11 -05:00
parent 94d04f2250
commit 2bda0ce351
3 changed files with 39 additions and 2 deletions

Binary file not shown.

View File

@ -5,6 +5,7 @@
// UE includes // UE includes
#include "Components/CapsuleComponent.h" #include "Components/CapsuleComponent.h"
#include "GameFramework/Character.h" #include "GameFramework/Character.h"
#include "Kismet/KismetMathLibrary.h"
// These are defined in CharacterMovementComponent.cpp and inaccessible here. Just copy and paste too make the PhysFalling work // These are defined in CharacterMovementComponent.cpp and inaccessible here. Just copy and paste too make the PhysFalling work
namespace CharacterMovementConstants namespace CharacterMovementConstants
@ -596,6 +597,40 @@ bool UGSCharacterMovementComponent::IsWalkable(const FHitResult& Hit) const
} }
bool UGSCharacterMovementComponent::FloorSweepTest(FHitResult& OutHit, const FVector& Start, const FVector& End,
ECollisionChannel TraceChannel, const FCollisionShape& CollisionShape, const FCollisionQueryParams& Params,
const FCollisionResponseParams& ResponseParam) const
{
bool bBlockingHit = false;
if (!bUseFlatBaseForFloorChecks)
{
bool IsUp = FMath::Abs(CharacterUpDirection.Dot(FVector::UpVector)) > UE_KINDA_SMALL_NUMBER;
FQuat Rot = UKismetMathLibrary::RotatorFromAxisAndAngle(FVector::ForwardVector, IsUp ? 0.0f : 90.0f).Quaternion();
bBlockingHit = GetWorld()->SweepSingleByChannel(OutHit, Start, End, Rot, TraceChannel, CollisionShape, Params, ResponseParam);
}
else
{
// Test with a box that is enclosed by the capsule.
const float CapsuleRadius = CollisionShape.GetCapsuleRadius();
const float CapsuleHeight = CollisionShape.GetCapsuleHalfHeight();
const FCollisionShape BoxShape = FCollisionShape::MakeBox(FVector(CapsuleRadius * 0.707f, CapsuleRadius * 0.707f, CapsuleHeight));
// First test with the box rotated so the corners are along the major axes (ie rotated 45 degrees).
bBlockingHit = GetWorld()->SweepSingleByChannel(OutHit, Start, End, FQuat(FVector(0.f, 0.f, -1.f), UE_PI * 0.25f), TraceChannel, BoxShape, Params, ResponseParam);
if (!bBlockingHit)
{
// Test again with the same box, not rotated.
OutHit.Reset(1.f, false);
bBlockingHit = GetWorld()->SweepSingleByChannel(OutHit, Start, End, FQuat::Identity, TraceChannel, BoxShape, Params, ResponseParam);
}
}
return bBlockingHit;
}
void UGSCharacterMovementComponent::SetCharacterUpDirection(FVector NewUpDirection) void UGSCharacterMovementComponent::SetCharacterUpDirection(FVector NewUpDirection)
{ {

View File

@ -30,6 +30,8 @@ public:
virtual bool IsValidLandingSpot(const FVector& CapsuleLocation, const FHitResult& Hit) const override; virtual bool IsValidLandingSpot(const FVector& CapsuleLocation, const FHitResult& Hit) const override;
virtual bool IsWalkable(const FHitResult& Hit) const override; virtual bool IsWalkable(const FHitResult& Hit) const override;
virtual bool FloorSweepTest(FHitResult& OutHit, const FVector& Start, const FVector& End, ECollisionChannel TraceChannel, const FCollisionShape& CollisionShape, const FCollisionQueryParams& Params, const FCollisionResponseParams& ResponseParam) const override;
// End UCharacterMovementComponent interface // End UCharacterMovementComponent interface
private: private: