Beginnings of a better dash

This commit is contained in:
Kevin Poretti 2022-03-23 22:30:47 -04:00
parent 0ab46a246c
commit 3957886ff8
79 changed files with 310 additions and 151 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
SwordNGun/Content/Maps/MovementTest.umap (Stored with Git LFS)

Binary file not shown.

View File

@ -3,6 +3,7 @@
#include "Components/SNGCharacterMovementComponent.h"
#include "GameFramework/Character.h"
#include "Kismet/KismetMathLibrary.h"
#include "PhysicsEngine/PhysicsSettings.h"
@ -32,8 +33,17 @@ USNGCharacterMovementComponent::USNGCharacterMovementComponent()
// jump
MaxJumpHeight = 250.0f;
DesiredJumpDuration = 0.75f;
ComputerGravityScaleAndJumpZVelocity();
ComputeGravityScaleAndJumpZVelocity();
// dash
DashVelocity = 1000.0f;
DashGroundFriction = 0.0f;
DashGravityScale = 0.1f;
DashFloatTime = 0.2f;
DashSlideTime = 0.5f;
DashGravityToDefaultSpeed = 5.0f;
DashGroundFrictionToDefaultSpeed = 5.0f;
/*
// not used...yet
MinJumpHeight = 200.0f;
@ -58,14 +68,33 @@ USNGCharacterMovementComponent::USNGCharacterMovementComponent()
*/
void USNGCharacterMovementComponent::RestoreMovementDefaults()
{
GroundFriction = DefaultGroundFriction;
GravityScale = DefaultGravityScale;
GroundFriction = TargetGroundFriction = DefaultGroundFriction;
GravityScale = TargetGravityScale = DefaultGravityScale;
RotationRate = DefaultRotationRate;
MaxWalkSpeed = DefaultMaxWalkSpeed;
MaxWalkSpeed = TargetMaxWalkSpeed = DefaultMaxWalkSpeed;
AirControl = DefaultAirControl;
JumpZVelocity = DefaultJumpZVelocity;
}
void USNGCharacterMovementComponent::Dash()
{
GroundFriction = DashGroundFriction;
GravityScale = DashGravityScale;
FloatTime = DashFloatTime;
SlideTime = DashSlideTime;
// sets gravity and friction targets which will start interpolating after float time and slide time elapse respectively
TargetGravityScale = DefaultGravityScale;
TargetGroundFriction = DefaultGroundFriction;
GravityScaleInterpSpeed = DashGravityToDefaultSpeed;
GroundFrictionInterpSpeed = DashGroundFrictionToDefaultSpeed;
FRotator CharacterRot = FRotator(0.0f, GetCharacterOwner()->GetActorRotation().Yaw, 0.0f);
FVector LaunchDir = FVector(UKismetMathLibrary::GetForwardVector(CharacterRot));
LaunchDir.Normalize();
Launch(LaunchDir * DashVelocity);
}
#if WITH_EDITOR
void USNGCharacterMovementComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
@ -76,7 +105,7 @@ void USNGCharacterMovementComponent::PostEditChangeProperty(FPropertyChangedEven
PropertyThatChanged && PropertyThatChanged->GetFName() == GET_MEMBER_NAME_CHECKED(USNGCharacterMovementComponent, DesiredJumpDuration))
{
// Compute WalkableFloorZ from the Angle.
ComputerGravityScaleAndJumpZVelocity();
ComputeGravityScaleAndJumpZVelocity();
}
}
@ -85,16 +114,17 @@ void USNGCharacterMovementComponent::PostLoad()
Super::PostLoad();
// Compute gravity scale and jump z velocity for first time
ComputerGravityScaleAndJumpZVelocity();
ComputeGravityScaleAndJumpZVelocity();
}
#endif // WITH_EDITOR
void USNGCharacterMovementComponent::OnSprintTimer()
{
bIsSprinting = true;
TargetMaxWalkSpeed = SprintingMaxWalkSpeed;
}
void USNGCharacterMovementComponent::ComputerGravityScaleAndJumpZVelocity()
void USNGCharacterMovementComponent::ComputeGravityScaleAndJumpZVelocity()
{
float HalfJumpDuration = DesiredJumpDuration / 2.0f;
DefaultJumpZVelocity = (2 * MaxJumpHeight) / HalfJumpDuration;
@ -125,6 +155,44 @@ void USNGCharacterMovementComponent::AddJumpForce()
*/
}
void USNGCharacterMovementComponent::InterpolateMovementParameters(float DeltaTime)
{
// set walk speed
MaxWalkSpeed = FMath::FInterpTo(MaxWalkSpeed, TargetMaxWalkSpeed, DeltaTime, MaxWalkSpeedInterpSpeed);
// ground friction
if(SlideTime > 0.0f)
{
SlideTime = FMath::Max(SlideTime - DeltaTime * GetCharacterOwner()->CustomTimeDilation, 0.0f);
}
else
{
GroundFriction = FMath::FInterpTo(GroundFriction, TargetGroundFriction, DeltaTime, GroundFrictionInterpSpeed);
}
// gravity scale
if(FloatTime > 0.0f)
{
FloatTime = FMath::Max(FloatTime - DeltaTime * GetCharacterOwner()->CustomTimeDilation, 0.0f);
}
else
{
GravityScale = FMath::FInterpTo(GravityScale, TargetGravityScale, DeltaTime, GravityScaleInterpSpeed);
}
// set rotation rate
// NOTE(kevin): since default rotate rate is 360 RInterpTo will go from 0 to 180 instead of 360 to 180
// need to think of a way to prevent this
// might just need to do my own interp manually
/*
FRotator TargetRotationRate = bIsSprinting ? SprintingRotationRate : DefaultRotationRate;
FRotator NewRotationRate = FMath::RInterpTo(RotationRate, TargetRotationRate, DeltaTime, WalkToSprintInterpSpeed);
RotationRate = NewRotationRate;
*/
// gravity
}
void USNGCharacterMovementComponent::BeginPlay()
{
Super::BeginPlay();
@ -139,30 +207,23 @@ void USNGCharacterMovementComponent::TickComponent(float DeltaTime, ELevelTick T
Super::TickComponent(DeltaTime, Tick, ThisTickFunction);
float LateralSpeed = Velocity.Size2D();
if(LateralSpeed >= SprintLateralSpeedThreshold && !GetWorld()->GetTimerManager().IsTimerActive(TimerHandle_SprintTimer) )
if(LateralSpeed >= SprintLateralSpeedThreshold && !GetWorld()->GetTimerManager().IsTimerActive(TimerHandle_SprintTimer))
{
GetWorld()->GetTimerManager().SetTimer(TimerHandle_SprintTimer,
this, &USNGCharacterMovementComponent::OnSprintTimer,
TimeToInitiateSprint, false);
}
if(LateralSpeed < SprintLateralSpeedThreshold && GetWorld()->GetTimerManager().IsTimerActive(TimerHandle_SprintTimer))
if(LateralSpeed < SprintLateralSpeedThreshold)
{
GetWorld()->GetTimerManager().ClearTimer(TimerHandle_SprintTimer);
if(GetWorld()->GetTimerManager().IsTimerActive(TimerHandle_SprintTimer))
{
GetWorld()->GetTimerManager().ClearTimer(TimerHandle_SprintTimer);
}
bIsSprinting = false;
TargetMaxWalkSpeed = DefaultMaxWalkSpeed;
MaxWalkSpeedInterpSpeed = WalkToSprintInterpSpeed;
}
// set walk speed and rotation rate depending on whether player is sprinting or not
float TargetMaxWalkSpeed = bIsSprinting ? SprintingMaxWalkSpeed : DefaultMaxWalkSpeed;
float NewMaxWalkSpeed = FMath::FInterpTo(MaxWalkSpeed, TargetMaxWalkSpeed, DeltaTime, WalkToSprintInterpSpeed);
MaxWalkSpeed = NewMaxWalkSpeed;
// NOTE(kevin): since default rotate rate is 360 RInterpTo will go from 0 to 180 instead of 360 to 180
// need to think of a way to prevent this
// might just need to do my own interp manually
/*
FRotator TargetRotationRate = bIsSprinting ? SprintingRotationRate : DefaultRotationRate;
FRotator NewRotationRate = FMath::RInterpTo(RotationRate, TargetRotationRate, DeltaTime, WalkToSprintInterpSpeed);
RotationRate = NewRotationRate;
*/
InterpolateMovementParameters(DeltaTime);
}

View File

@ -36,7 +36,10 @@ protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Animations")
UAnimMontage* JumpBackMontage;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Animations")
UAnimMontage* DashMontage;
UPROPERTY(BlueprintReadWrite)
bool CanMove;
@ -64,7 +67,7 @@ protected:
void LookUpRate(float Value);
void StartJump();
virtual void Landed(const FHitResult& Hit) override;
// Called when the game starts or when spawned

View File

@ -28,6 +28,9 @@ public:
*/
UFUNCTION(BlueprintCallable)
void RestoreMovementDefaults();
UFUNCTION(BlueprintCallable)
void Dash();
/**
* Gets bool whether the character is currently in the sprinting state
@ -39,48 +42,66 @@ public:
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif // WITH_EDITOR
protected:
// default ground
/** Default friction when not performing any special actions and on the ground */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Ground|Defaults", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Defaults|Ground", meta=(ClampMin="0", UIMin="0"))
float DefaultGroundFriction;
/** Ground friction we want character to interpolate to. Interpolated based on GroundFrictionInterpSpeed. */
UPROPERTY(BlueprintReadWrite)
float TargetGroundFriction;
/** How fast current GroundFriction will be interpolated to TargetGroundFriction */
UPROPERTY(BlueprintReadWrite)
float GroundFrictionInterpSpeed;
/** Timer used to determine when to start interpolating GroundFriction back to TargetGroundFriction */
UPROPERTY(BlueprintReadWrite)
float SlideTime;
/** Default ground walk speed when not performing any special actions */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Ground|Defaults", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Defaults|Ground", meta=(ClampMin="0", UIMin="0"))
float DefaultMaxWalkSpeed;
/** Current MaxWalkSpeed we want to character to walk at. Interpolated based on MaxWalkSpeedInterpSpeed. */
UPROPERTY(BlueprintReadWrite)
float TargetMaxWalkSpeed;
UPROPERTY(BlueprintReadWrite)
/** How fast current MaxWalkSpeed will be interpolated to TargetMaxWalkSpeed */
float MaxWalkSpeedInterpSpeed;
/** Default ground walk speed when not performing any special actions */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Ground|Defaults", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Defaults|Ground", meta=(ClampMin="0", UIMin="0"))
FRotator DefaultRotationRate;
// sprinting
/** Ground walk speed when sprinting */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Ground|Sprint", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Sprint", meta=(ClampMin="0", UIMin="0"))
float SprintingMaxWalkSpeed;
/** Lateral speed the player needs to maintain to stay in the sprinting state */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Ground|Sprint", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Sprint", meta=(ClampMin="0", UIMin="0"))
float SprintLateralSpeedThreshold;
/** Default ground walk speed when not performing any special actions */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Ground|Sprint", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Sprint", meta=(ClampMin="0", UIMin="0"))
FRotator SprintingRotationRate;
/** How long after applying movement input should the character start sprinting? */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Ground|Sprint", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Sprint", meta=(ClampMin="0", UIMin="0"))
float TimeToInitiateSprint;
/** The speed in which the max walk speed to interpolated to the max sprint speed when a sprint has been initiated */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Ground|Sprint", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Sprint", meta=(ClampMin="0", UIMin="0"))
float WalkToSprintInterpSpeed;
FTimerHandle TimerHandle_SprintTimer;
UPROPERTY(BlueprintReadOnly)
bool bIsSprinting;
void OnSprintTimer();
// firing
@ -95,19 +116,31 @@ protected:
// airborne
/** Gravity scale when not performing any special actions */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="SNG Character Movement|Air|Defaults", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="SNG Character Movement|Defaults|Air", meta=(ClampMin="0", UIMin="0"))
float DefaultGravityScale;
/** How much to dampen lateral velocities at the start of a jump */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Air|Defaults", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Defaults|Air", meta=(ClampMin="0", UIMin="0"))
float LateralVelocityDampening;
/** Gravity Scale we want character to interpolate to. Interpolated based on GravityScaleInterpSpeed. */
UPROPERTY(BlueprintReadWrite)
float TargetGravityScale;
/** How fast current GravityScale will be interpolated to TargetGravityScale */
UPROPERTY(BlueprintReadWrite)
float GravityScaleInterpSpeed;
/** Timer used to determine when to start interpolating GravityScale back to TargetGravityScale */
UPROPERTY(BlueprintReadWrite)
float FloatTime;
/**
* How high (Z) is the character able to reach when holding the jump button for the maximum allowed time.
*
* This is used in conjunction with DesiredJumpDuration to derive DefaultGravityScale and JumpZVelocity.
*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Air|Jump", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Jump", meta=(ClampMin="0", UIMin="0"))
float MaxJumpHeight;
/**
@ -116,22 +149,22 @@ protected:
*
* This is used in conjunction with MaxJumpHeight to derive DefaultGravityScale and JumpZVelocity.
*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Air|Jump", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Jump", meta=(ClampMin="0", UIMin="0"))
float DesiredJumpDuration;
/** Force to continuously apply to character when they are holding the jump button */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="SNG Character Movement|Air|Jump", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="SNG Character Movement|Jump", meta=(ClampMin="0", UIMin="0"))
float DefaultJumpZVelocity;
/** Minimum height a character must reach before jump force is no longer applied even if the jump input is not being held */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Air|Jump", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Jump", meta=(ClampMin="0", UIMin="0"))
float MinJumpHeight;
/** Max time the jump button can be held to give character upward velocity */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Air|Jump", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Jump", meta=(ClampMin="0", UIMin="0"))
float MaxJumpTime;
void ComputerGravityScaleAndJumpZVelocity();
void ComputeGravityScaleAndJumpZVelocity();
/**
* Sets up character velocities and jump parameters like the jump timer
@ -146,16 +179,54 @@ protected:
void AddJumpForce();
/** Default friction when not performing any special actions and in the air */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Air|Defaults", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Defaults|Air", meta=(ClampMin="0", UIMin="0"))
float DefaultAirControl;
/** Minimum distance from the ground a character has to be to be able to perform an air dash */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Air|Defaults", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Defaults|Air", meta=(ClampMin="0", UIMin="0"))
float MinAllowedDashHeight;
/** Minimum distance from the ground a character has to be to be able to perform an air attack */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Air|Defaults", meta=(ClampMin="0", UIMin="0"))
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Defaults|Air", meta=(ClampMin="0", UIMin="0"))
float MinAllowedAttackHeight;
/** Initial lateral velocity when the character dashes */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Dash", meta=(ClampMin="0", UIMin="0"))
float DashVelocity;
/** Initial ground friction when the character dashes */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Dash", meta=(ClampMin="0", UIMin="0"))
float DashGroundFriction;
/** Initial gravity scale when the character dashes */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Dash", meta=(ClampMin="0", UIMin="0"))
float DashGravityScale;
/** How long the character should "float" before the gravity scale is interpolated back to default */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Dash", meta=(ClampMin="0", UIMin="0"))
float DashFloatTime;
/** How fast default gravity scale will be interpolated to after dash is done */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Dash", meta=(ClampMin="0", UIMin="0"))
float DashGravityToDefaultSpeed;
/** How long the character should "slide" before the ground friction is interpolated back to default */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Dash", meta=(ClampMin="0", UIMin="0"))
float DashSlideTime;
/** How fast default ground friction will be interpolated to after dash is done */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement|Dash", meta=(ClampMin="0", UIMin="0"))
float DashGroundFrictionToDefaultSpeed;
/**
* @brief Interpolates current movement parameters (i.e. GravityScale, MaxWalkSpeed, GroundFrinction) to the values
* specified by the parameters corresponding target value (i.e. GravityScale will be interpolated to TargetGravityScale).
* The interpolation speed is determined by the parameters corresponding speed value (i.e. GravityScale is interpolated
* to TargetGravityScale by a speed of GravityScaleInterpSpeed).
*
* This function is called every component tick.
*/
void InterpolateMovementParameters(float DeltaTime);
virtual void BeginPlay() override;