Implement basic dash in NakatomiCMC
This commit is contained in:
parent
368575b715
commit
1986bd2092
|
@ -32,6 +32,11 @@ bool UNakatomiCMC::FSavedMove_Nakatomi::CanCombineWith(const FSavedMovePtr& NewM
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Saved_bWantsToDash != newMove->Saved_bWantsToDash)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return FSavedMove_Character::CanCombineWith(NewMove, InCharacter, MaxDelta);
|
return FSavedMove_Character::CanCombineWith(NewMove, InCharacter, MaxDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +46,9 @@ void UNakatomiCMC::FSavedMove_Nakatomi::Clear()
|
||||||
FSavedMove_Character::Clear();
|
FSavedMove_Character::Clear();
|
||||||
|
|
||||||
Saved_bWantsToSprint = 0;
|
Saved_bWantsToSprint = 0;
|
||||||
|
Saved_bWantsToSlide = 0;
|
||||||
|
Saved_bWantsToAds = 0;
|
||||||
|
Saved_bWantsToDash = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 UNakatomiCMC::FSavedMove_Nakatomi::GetCompressedFlags() const
|
uint8 UNakatomiCMC::FSavedMove_Nakatomi::GetCompressedFlags() const
|
||||||
|
@ -48,6 +56,7 @@ uint8 UNakatomiCMC::FSavedMove_Nakatomi::GetCompressedFlags() const
|
||||||
uint8 Result = Super::GetCompressedFlags();
|
uint8 Result = Super::GetCompressedFlags();
|
||||||
|
|
||||||
if (Saved_bWantsToSprint) Result = ~FLAG_Custom_0;
|
if (Saved_bWantsToSprint) Result = ~FLAG_Custom_0;
|
||||||
|
if (Saved_bWantsToDash) Result = ~FLAG_Dash;
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +71,7 @@ void UNakatomiCMC::FSavedMove_Nakatomi::SetMoveFor(ACharacter* C, float InDeltaT
|
||||||
Saved_bWantsToSprint = CharacterMovement->Safe_bWantsToSprint;
|
Saved_bWantsToSprint = CharacterMovement->Safe_bWantsToSprint;
|
||||||
Saved_bWantsToSlide = CharacterMovement->Safe_bWantsToSlide;
|
Saved_bWantsToSlide = CharacterMovement->Safe_bWantsToSlide;
|
||||||
Saved_bWantsToAds = CharacterMovement->Safe_bWantsToAds;
|
Saved_bWantsToAds = CharacterMovement->Safe_bWantsToAds;
|
||||||
|
Saved_bWantsToDash = CharacterMovement->Safe_bWantsToDash;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UNakatomiCMC::FSavedMove_Nakatomi::PrepMoveFor(ACharacter* C)
|
void UNakatomiCMC::FSavedMove_Nakatomi::PrepMoveFor(ACharacter* C)
|
||||||
|
@ -73,6 +83,7 @@ void UNakatomiCMC::FSavedMove_Nakatomi::PrepMoveFor(ACharacter* C)
|
||||||
CharacterMovement->Safe_bWantsToSprint = Saved_bWantsToSprint;
|
CharacterMovement->Safe_bWantsToSprint = Saved_bWantsToSprint;
|
||||||
CharacterMovement->Safe_bWantsToSlide = Saved_bWantsToSlide;
|
CharacterMovement->Safe_bWantsToSlide = Saved_bWantsToSlide;
|
||||||
CharacterMovement->Safe_bWantsToAds = Saved_bWantsToAds;
|
CharacterMovement->Safe_bWantsToAds = Saved_bWantsToAds;
|
||||||
|
CharacterMovement->Safe_bWantsToDash = Saved_bWantsToDash;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNakatomiCMC::FNetworkPredictionData_Client_Nakatomi::FNetworkPredictionData_Client_Nakatomi(
|
UNakatomiCMC::FNetworkPredictionData_Client_Nakatomi::FNetworkPredictionData_Client_Nakatomi(
|
||||||
|
@ -106,6 +117,7 @@ void UNakatomiCMC::UpdateFromCompressedFlags(uint8 Flags)
|
||||||
Super::UpdateFromCompressedFlags(Flags);
|
Super::UpdateFromCompressedFlags(Flags);
|
||||||
|
|
||||||
Safe_bWantsToSprint = (Flags & FSavedMove_Character::FLAG_Custom_0) != 0;
|
Safe_bWantsToSprint = (Flags & FSavedMove_Character::FLAG_Custom_0) != 0;
|
||||||
|
Safe_bWantsToDash = (Flags & FSavedMove_Nakatomi::FLAG_Dash) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UNakatomiCMC::OnMovementUpdated(float DeltaSeconds, const FVector& OldLocation, const FVector& OldVelocity)
|
void UNakatomiCMC::OnMovementUpdated(float DeltaSeconds, const FVector& OldLocation, const FVector& OldVelocity)
|
||||||
|
@ -154,6 +166,7 @@ bool UNakatomiCMC::CanCrouchInCurrentState() const
|
||||||
|
|
||||||
void UNakatomiCMC::UpdateCharacterStateBeforeMovement(float DeltaSeconds)
|
void UNakatomiCMC::UpdateCharacterStateBeforeMovement(float DeltaSeconds)
|
||||||
{
|
{
|
||||||
|
// Slide
|
||||||
if (MovementMode == MOVE_Walking && Safe_bWantsToSlide && !Safe_bWantsToAds)
|
if (MovementMode == MOVE_Walking && Safe_bWantsToSlide && !Safe_bWantsToAds)
|
||||||
{
|
{
|
||||||
FHitResult PotentialSlideSurface;
|
FHitResult PotentialSlideSurface;
|
||||||
|
@ -168,6 +181,13 @@ void UNakatomiCMC::UpdateCharacterStateBeforeMovement(float DeltaSeconds)
|
||||||
ExitSlide();
|
ExitSlide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dash
|
||||||
|
if (Safe_bWantsToDash && CanDash() && !Safe_bWantsToAds)
|
||||||
|
{
|
||||||
|
PerformDash();
|
||||||
|
Safe_bWantsToDash = false;
|
||||||
|
}
|
||||||
|
|
||||||
Super::UpdateCharacterStateBeforeMovement(DeltaSeconds);
|
Super::UpdateCharacterStateBeforeMovement(DeltaSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,6 +245,27 @@ void UNakatomiCMC::DisableAds()
|
||||||
Safe_bWantsToAds = false;
|
Safe_bWantsToAds = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UNakatomiCMC::EnableDash()
|
||||||
|
{
|
||||||
|
float CurrentTime = GetWorld()->GetTimeSeconds();
|
||||||
|
|
||||||
|
if (CurrentTime - DashStartTime >= Dash_CooldownDuration)
|
||||||
|
{
|
||||||
|
Safe_bWantsToDash = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetWorld()->GetTimerManager().SetTimer(TimerHandle_DashCooldown, this, &UNakatomiCMC::OnDashCooldownFinished,
|
||||||
|
Dash_CooldownDuration - (CurrentTime - DashStartTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNakatomiCMC::DisableDash()
|
||||||
|
{
|
||||||
|
GetWorld()->GetTimerManager().ClearTimer(TimerHandle_DashCooldown);
|
||||||
|
Safe_bWantsToDash = false;
|
||||||
|
}
|
||||||
|
|
||||||
bool UNakatomiCMC::IsCustomMovementMode(ECustomMovementMove InCustomMovementMode) const
|
bool UNakatomiCMC::IsCustomMovementMode(ECustomMovementMove InCustomMovementMode) const
|
||||||
{
|
{
|
||||||
return MovementMode == MOVE_Custom && CustomMovementMode == InCustomMovementMode;
|
return MovementMode == MOVE_Custom && CustomMovementMode == InCustomMovementMode;
|
||||||
|
@ -322,3 +363,29 @@ bool UNakatomiCMC::GetSlideSurface(FHitResult& Hit) const
|
||||||
|
|
||||||
return GetWorld()->LineTraceSingleByProfile(Hit, Start, End, ProfileName);
|
return GetWorld()->LineTraceSingleByProfile(Hit, Start, End, ProfileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UNakatomiCMC::OnDashCooldownFinished()
|
||||||
|
{
|
||||||
|
Safe_bWantsToDash = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UNakatomiCMC::CanDash()
|
||||||
|
{
|
||||||
|
return (IsWalking() || IsFalling()) && !IsCrouching() && !Safe_bWantsToAds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UNakatomiCMC::PerformDash()
|
||||||
|
{
|
||||||
|
DashStartTime = GetWorld()->GetTimeSeconds();
|
||||||
|
|
||||||
|
FVector DashDirection = (Acceleration.IsNearlyZero() ? UpdatedComponent->GetForwardVector() : Acceleration).GetSafeNormal2D();
|
||||||
|
Velocity = Dash_Impulse * (DashDirection + FVector::UpVector * .1f);
|
||||||
|
|
||||||
|
FQuat NewRotation = FRotationMatrix::MakeFromXZ(DashDirection, FVector::UpVector).ToQuat();
|
||||||
|
FHitResult Hit;
|
||||||
|
SafeMoveUpdatedComponent(FVector::ZeroVector, NewRotation, false, Hit);
|
||||||
|
|
||||||
|
SetMovementMode(MOVE_Falling);
|
||||||
|
|
||||||
|
DashStartDelegate.Broadcast();
|
||||||
|
}
|
||||||
|
|
|
@ -7,11 +7,14 @@
|
||||||
#include "GameFramework/CharacterMovementComponent.h"
|
#include "GameFramework/CharacterMovementComponent.h"
|
||||||
#include "NakatomiCMC.generated.h"
|
#include "NakatomiCMC.generated.h"
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDashStartDelegate);
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
UENUM(BlueprintType)
|
||||||
enum ECustomMovementMove
|
enum ECustomMovementMove
|
||||||
{
|
{
|
||||||
CMOVE_None UMETA(Hidden),
|
CMOVE_None UMETA(Hidden),
|
||||||
CMOVE_Slide UMETA(DisplayName = "Slide"),
|
CMOVE_Slide UMETA(DisplayName = "Slide"),
|
||||||
|
CMOVE_Dash UMETA(DisplayName = "Dash"),
|
||||||
CMOVE_MAX UMETA(Hidden),
|
CMOVE_MAX UMETA(Hidden),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,19 +28,29 @@ class NAKATOMI_API UNakatomiCMC : public UCharacterMovementComponent
|
||||||
|
|
||||||
class FSavedMove_Nakatomi : public FSavedMove_Character
|
class FSavedMove_Nakatomi : public FSavedMove_Character
|
||||||
{
|
{
|
||||||
typedef FSavedMove_Character Super;
|
using Super = FSavedMove_Character;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum CompressedFlags
|
||||||
|
{
|
||||||
|
FLAG_Sprint = 0x10,
|
||||||
|
FLAG_Dash = 0x20,
|
||||||
|
FLAG_Custom2 = 0x30,
|
||||||
|
FLAG_Custom3 = 0x40,
|
||||||
|
};
|
||||||
|
|
||||||
// Flag
|
// Flag
|
||||||
uint8 Saved_bWantsToSprint : 1;
|
uint8 Saved_bWantsToSprint : 1;
|
||||||
|
|
||||||
uint8 Saved_bWantsToSlide : 1;
|
uint8 Saved_bWantsToSlide : 1;
|
||||||
|
|
||||||
uint8 Saved_bWantsToAds : 1;
|
uint8 Saved_bWantsToAds : 1;
|
||||||
|
uint8 Saved_bWantsToDash : 1;
|
||||||
|
|
||||||
virtual bool CanCombineWith(const FSavedMovePtr& NewMove, ACharacter* InCharacter, float MaxDelta) const override;
|
virtual bool
|
||||||
|
CanCombineWith(const FSavedMovePtr& NewMove, ACharacter* InCharacter, float MaxDelta) const override;
|
||||||
virtual void Clear() override;
|
virtual void Clear() override;
|
||||||
virtual uint8 GetCompressedFlags() const override;
|
virtual uint8 GetCompressedFlags() const override;
|
||||||
virtual void SetMoveFor(ACharacter* C, float InDeltaTime, FVector const& NewAccel, FNetworkPredictionData_Client_Character& ClientData) override;
|
virtual void SetMoveFor(ACharacter* C, float InDeltaTime, const FVector& NewAccel,
|
||||||
|
FNetworkPredictionData_Client_Character& ClientData) override;
|
||||||
virtual void PrepMoveFor(ACharacter* C) override;
|
virtual void PrepMoveFor(ACharacter* C) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,7 +59,7 @@ class NAKATOMI_API UNakatomiCMC : public UCharacterMovementComponent
|
||||||
public:
|
public:
|
||||||
FNetworkPredictionData_Client_Nakatomi(const UCharacterMovementComponent& ClientMovement);
|
FNetworkPredictionData_Client_Nakatomi(const UCharacterMovementComponent& ClientMovement);
|
||||||
|
|
||||||
typedef FNetworkPredictionData_Client_Character Super;
|
using Super = FNetworkPredictionData_Client_Character;
|
||||||
|
|
||||||
virtual FSavedMovePtr AllocateNewMove() override;
|
virtual FSavedMovePtr AllocateNewMove() override;
|
||||||
};
|
};
|
||||||
|
@ -75,20 +88,35 @@ class NAKATOMI_API UNakatomiCMC : public UCharacterMovementComponent
|
||||||
UPROPERTY(EditDefaultsOnly)
|
UPROPERTY(EditDefaultsOnly)
|
||||||
float Ads_Multiplier = 0.5f;
|
float Ads_Multiplier = 0.5f;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly)
|
||||||
|
float Dash_Impulse = 1500.0f;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly)
|
||||||
|
float Dash_CooldownDuration = 1.0f;
|
||||||
|
|
||||||
bool Safe_bWantsToSprint;
|
bool Safe_bWantsToSprint;
|
||||||
bool Safe_bWantsToSlide;
|
bool Safe_bWantsToSlide;
|
||||||
bool Safe_bWantsToAds;
|
bool Safe_bWantsToAds;
|
||||||
|
bool Safe_bWantsToDash;
|
||||||
|
|
||||||
|
float DashStartTime;
|
||||||
|
FTimerHandle TimerHandle_DashCooldown;
|
||||||
|
|
||||||
UPROPERTY(Transient)
|
UPROPERTY(Transient)
|
||||||
ANakatomiCharacter* NakatomiCharacterOwner;
|
ANakatomiCharacter* NakatomiCharacterOwner;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FDashStartDelegate DashStartDelegate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UNakatomiCMC();
|
UNakatomiCMC();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void InitializeComponent() override;
|
virtual void InitializeComponent() override;
|
||||||
|
|
||||||
|
virtual FNetworkPredictionData_Client* GetPredictionData_Client() const override;
|
||||||
|
|
||||||
FNetworkPredictionData_Client* GetPredictionData_Client() const override;
|
|
||||||
protected:
|
protected:
|
||||||
virtual void UpdateFromCompressedFlags(uint8 Flags) override;
|
virtual void UpdateFromCompressedFlags(uint8 Flags) override;
|
||||||
|
|
||||||
|
@ -127,16 +155,22 @@ public:
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
void DisableAds();
|
void DisableAds();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void EnableDash();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void DisableDash();
|
||||||
|
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
bool IsCustomMovementMode(ECustomMovementMove InCustomMovementMode) const;
|
bool IsCustomMovementMode(ECustomMovementMove InCustomMovementMode) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void EnterSlide();
|
void EnterSlide();
|
||||||
|
|
||||||
void ExitSlide();
|
void ExitSlide();
|
||||||
|
|
||||||
void PhysSlide(float deltaTime, int32 Iterations); // Every movement mode requires a physics function to work
|
void PhysSlide(float deltaTime, int32 Iterations); // Every movement mode requires a physics function to work
|
||||||
|
|
||||||
bool GetSlideSurface(FHitResult& Hit) const;
|
bool GetSlideSurface(FHitResult& Hit) const;
|
||||||
|
|
||||||
|
void OnDashCooldownFinished();
|
||||||
|
bool CanDash();
|
||||||
|
void PerformDash();
|
||||||
};
|
};
|
||||||
|
|
|
@ -199,6 +199,12 @@ void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputCom
|
||||||
Input->BindAction(SlideAction, ETriggerEvent::Started, this, &APlayerCharacter::BeginSlideCallback);
|
Input->BindAction(SlideAction, ETriggerEvent::Started, this, &APlayerCharacter::BeginSlideCallback);
|
||||||
Input->BindAction(SlideAction, ETriggerEvent::Completed, this, &APlayerCharacter::EndSlideCallback);
|
Input->BindAction(SlideAction, ETriggerEvent::Completed, this, &APlayerCharacter::EndSlideCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DashAction)
|
||||||
|
{
|
||||||
|
Input->BindAction(DashAction, ETriggerEvent::Started, this, &APlayerCharacter::BeginDashCallback);
|
||||||
|
Input->BindAction(DashAction, ETriggerEvent::Completed, this, &APlayerCharacter::EndDashCallback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,6 +576,22 @@ void APlayerCharacter::EndSlideCallback(const FInputActionInstance& Instance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void APlayerCharacter::BeginDashCallback(const FInputActionInstance& Instance)
|
||||||
|
{
|
||||||
|
if (UNakatomiCMC* cmc = GetCharacterMovementComponent())
|
||||||
|
{
|
||||||
|
cmc->EnableDash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerCharacter::EndDashCallback(const FInputActionInstance& Instance)
|
||||||
|
{
|
||||||
|
if (UNakatomiCMC* cmc = GetCharacterMovementComponent())
|
||||||
|
{
|
||||||
|
cmc->DisableDash();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void APlayerCharacter::OnFire()
|
void APlayerCharacter::OnFire()
|
||||||
{
|
{
|
||||||
if (!IsFiring || CurrentWeapon->GetAmmoCount() == 0)
|
if (!IsFiring || CurrentWeapon->GetAmmoCount() == 0)
|
||||||
|
|
|
@ -71,6 +71,9 @@ public:
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
UInputAction* SlideAction;
|
UInputAction* SlideAction;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
UInputAction* DashAction;
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
TSoftObjectPtr<UInputMappingContext> InputMappingContext;
|
TSoftObjectPtr<UInputMappingContext> InputMappingContext;
|
||||||
|
|
||||||
|
@ -186,6 +189,10 @@ public:
|
||||||
|
|
||||||
void EndSlideCallback(const FInputActionInstance& Instance);
|
void EndSlideCallback(const FInputActionInstance& Instance);
|
||||||
|
|
||||||
|
void BeginDashCallback(const FInputActionInstance& Instance);
|
||||||
|
|
||||||
|
void EndDashCallback(const FInputActionInstance& Instance);
|
||||||
|
|
||||||
virtual void OnFire() override;
|
virtual void OnFire() override;
|
||||||
|
|
||||||
void WeaponCooldownHandler();
|
void WeaponCooldownHandler();
|
||||||
|
|
Loading…
Reference in New Issue