129 lines
4.0 KiB
C++
129 lines
4.0 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "LyraCharacterMovementComponent.h"
|
|
#include "GameFramework/Character.h"
|
|
#include "CollisionQueryParams.h"
|
|
#include "Components/CapsuleComponent.h"
|
|
#include "AbilitySystemGlobals.h"
|
|
#include "NativeGameplayTags.h"
|
|
#include "AbilitySystemComponent.h"
|
|
|
|
UE_DEFINE_GAMEPLAY_TAG(TAG_Gameplay_MovementStopped, "Gameplay.MovementStopped");
|
|
|
|
namespace LyraCharacter
|
|
{
|
|
static float GroundTraceDistance = 100000.0f;
|
|
FAutoConsoleVariableRef CVar_GroundTraceDistance(TEXT("LyraCharacter.GroundTraceDistance"), GroundTraceDistance, TEXT("Distance to trace down when generating ground information."), ECVF_Cheat);
|
|
};
|
|
|
|
|
|
ULyraCharacterMovementComponent::ULyraCharacterMovementComponent(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
}
|
|
|
|
void ULyraCharacterMovementComponent::SimulateMovement(float DeltaTime)
|
|
{
|
|
if (bHasReplicatedAcceleration)
|
|
{
|
|
// Preserve our replicated acceleration
|
|
const FVector OriginalAcceleration = Acceleration;
|
|
Super::SimulateMovement(DeltaTime);
|
|
Acceleration = OriginalAcceleration;
|
|
}
|
|
else
|
|
{
|
|
Super::SimulateMovement(DeltaTime);
|
|
}
|
|
}
|
|
|
|
bool ULyraCharacterMovementComponent::CanAttemptJump() const
|
|
{
|
|
// Same as UCharacterMovementComponent's implementation but without the crouch check
|
|
return IsJumpAllowed() &&
|
|
(IsMovingOnGround() || IsFalling()); // Falling included for double-jump and non-zero jump hold time, but validated by character.
|
|
}
|
|
|
|
void ULyraCharacterMovementComponent::InitializeComponent()
|
|
{
|
|
Super::InitializeComponent();
|
|
}
|
|
|
|
const FLyraCharacterGroundInfo& ULyraCharacterMovementComponent::GetGroundInfo()
|
|
{
|
|
if (!CharacterOwner || (GFrameCounter == CachedGroundInfo.LastUpdateFrame))
|
|
{
|
|
return CachedGroundInfo;
|
|
}
|
|
|
|
if (MovementMode == MOVE_Walking)
|
|
{
|
|
CachedGroundInfo.GroundHitResult = CurrentFloor.HitResult;
|
|
CachedGroundInfo.GroundDistance = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
const UCapsuleComponent* CapsuleComp = CharacterOwner->GetCapsuleComponent();
|
|
check(CapsuleComp);
|
|
|
|
const float CapsuleHalfHeight = CapsuleComp->GetUnscaledCapsuleHalfHeight();
|
|
const ECollisionChannel CollisionChannel = (UpdatedComponent ? UpdatedComponent->GetCollisionObjectType() : ECC_Pawn);
|
|
const FVector TraceStart(GetActorLocation());
|
|
const FVector TraceEnd(TraceStart.X, TraceStart.Y, (TraceStart.Z - LyraCharacter::GroundTraceDistance - CapsuleHalfHeight));
|
|
|
|
FCollisionQueryParams QueryParams(SCENE_QUERY_STAT(LyraCharacterMovementComponent_GetGroundInfo), false, CharacterOwner);
|
|
FCollisionResponseParams ResponseParam;
|
|
InitCollisionParams(QueryParams, ResponseParam);
|
|
|
|
FHitResult HitResult;
|
|
GetWorld()->LineTraceSingleByChannel(HitResult, TraceStart, TraceEnd, CollisionChannel, QueryParams, ResponseParam);
|
|
|
|
CachedGroundInfo.GroundHitResult = HitResult;
|
|
CachedGroundInfo.GroundDistance = LyraCharacter::GroundTraceDistance;
|
|
|
|
if (MovementMode == MOVE_NavWalking)
|
|
{
|
|
CachedGroundInfo.GroundDistance = 0.0f;
|
|
}
|
|
else if (HitResult.bBlockingHit)
|
|
{
|
|
CachedGroundInfo.GroundDistance = FMath::Max((HitResult.Distance - CapsuleHalfHeight), 0.0f);
|
|
}
|
|
}
|
|
|
|
CachedGroundInfo.LastUpdateFrame = GFrameCounter;
|
|
|
|
return CachedGroundInfo;
|
|
}
|
|
|
|
void ULyraCharacterMovementComponent::SetReplicatedAcceleration(const FVector& InAcceleration)
|
|
{
|
|
bHasReplicatedAcceleration = true;
|
|
Acceleration = InAcceleration;
|
|
}
|
|
|
|
FRotator ULyraCharacterMovementComponent::GetDeltaRotation(float DeltaTime) const
|
|
{
|
|
if (UAbilitySystemComponent* ASC = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetOwner()))
|
|
{
|
|
if (ASC->HasMatchingGameplayTag(TAG_Gameplay_MovementStopped))
|
|
{
|
|
return FRotator(0,0,0);
|
|
}
|
|
}
|
|
|
|
return Super::GetDeltaRotation(DeltaTime);
|
|
}
|
|
|
|
float ULyraCharacterMovementComponent::GetMaxSpeed() const
|
|
{
|
|
if (UAbilitySystemComponent* ASC = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetOwner()))
|
|
{
|
|
if (ASC->HasMatchingGameplayTag(TAG_Gameplay_MovementStopped))
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return Super::GetMaxSpeed();
|
|
} |