Merge movement-component #1
|
@ -32,6 +32,11 @@ bool UNakatomiCMC::FSavedMove_Nakatomi::CanCombineWith(const FSavedMovePtr& NewM
|
|||
return false;
|
||||
}
|
||||
|
||||
if (Saved_bWantsToDash != newMove->Saved_bWantsToDash)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return FSavedMove_Character::CanCombineWith(NewMove, InCharacter, MaxDelta);
|
||||
}
|
||||
|
||||
|
@ -41,6 +46,9 @@ void UNakatomiCMC::FSavedMove_Nakatomi::Clear()
|
|||
FSavedMove_Character::Clear();
|
||||
|
||||
Saved_bWantsToSprint = 0;
|
||||
Saved_bWantsToSlide = 0;
|
||||
Saved_bWantsToAds = 0;
|
||||
Saved_bWantsToDash = 0;
|
||||
}
|
||||
|
||||
uint8 UNakatomiCMC::FSavedMove_Nakatomi::GetCompressedFlags() const
|
||||
|
@ -48,6 +56,7 @@ uint8 UNakatomiCMC::FSavedMove_Nakatomi::GetCompressedFlags() const
|
|||
uint8 Result = Super::GetCompressedFlags();
|
||||
|
||||
if (Saved_bWantsToSprint) Result = ~FLAG_Custom_0;
|
||||
if (Saved_bWantsToDash) Result = ~FLAG_Dash;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
@ -62,6 +71,7 @@ void UNakatomiCMC::FSavedMove_Nakatomi::SetMoveFor(ACharacter* C, float InDeltaT
|
|||
Saved_bWantsToSprint = CharacterMovement->Safe_bWantsToSprint;
|
||||
Saved_bWantsToSlide = CharacterMovement->Safe_bWantsToSlide;
|
||||
Saved_bWantsToAds = CharacterMovement->Safe_bWantsToAds;
|
||||
Saved_bWantsToDash = CharacterMovement->Safe_bWantsToDash;
|
||||
}
|
||||
|
||||
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_bWantsToSlide = Saved_bWantsToSlide;
|
||||
CharacterMovement->Safe_bWantsToAds = Saved_bWantsToAds;
|
||||
CharacterMovement->Safe_bWantsToDash = Saved_bWantsToDash;
|
||||
}
|
||||
|
||||
UNakatomiCMC::FNetworkPredictionData_Client_Nakatomi::FNetworkPredictionData_Client_Nakatomi(
|
||||
|
@ -106,6 +117,7 @@ void UNakatomiCMC::UpdateFromCompressedFlags(uint8 Flags)
|
|||
Super::UpdateFromCompressedFlags(Flags);
|
||||
|
||||
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)
|
||||
|
@ -154,6 +166,7 @@ bool UNakatomiCMC::CanCrouchInCurrentState() const
|
|||
|
||||
void UNakatomiCMC::UpdateCharacterStateBeforeMovement(float DeltaSeconds)
|
||||
{
|
||||
// Slide
|
||||
if (MovementMode == MOVE_Walking && Safe_bWantsToSlide && !Safe_bWantsToAds)
|
||||
{
|
||||
FHitResult PotentialSlideSurface;
|
||||
|
@ -168,6 +181,13 @@ void UNakatomiCMC::UpdateCharacterStateBeforeMovement(float DeltaSeconds)
|
|||
ExitSlide();
|
||||
}
|
||||
|
||||
// Dash
|
||||
if (Safe_bWantsToDash && CanDash() && !Safe_bWantsToAds)
|
||||
{
|
||||
PerformDash();
|
||||
Safe_bWantsToDash = false;
|
||||
}
|
||||
|
||||
Super::UpdateCharacterStateBeforeMovement(DeltaSeconds);
|
||||
}
|
||||
|
||||
|
@ -225,6 +245,27 @@ void UNakatomiCMC::DisableAds()
|
|||
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
|
||||
{
|
||||
return MovementMode == MOVE_Custom && CustomMovementMode == InCustomMovementMode;
|
||||
|
@ -322,3 +363,29 @@ bool UNakatomiCMC::GetSlideSurface(FHitResult& Hit) const
|
|||
|
||||
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 "NakatomiCMC.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDashStartDelegate);
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum ECustomMovementMove
|
||||
{
|
||||
CMOVE_None UMETA(Hidden),
|
||||
CMOVE_Slide UMETA(DisplayName = "Slide"),
|
||||
CMOVE_Dash UMETA(DisplayName = "Dash"),
|
||||
CMOVE_MAX UMETA(Hidden),
|
||||
};
|
||||
|
||||
|
@ -25,19 +28,29 @@ class NAKATOMI_API UNakatomiCMC : public UCharacterMovementComponent
|
|||
|
||||
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
|
||||
uint8 Saved_bWantsToSprint:1;
|
||||
uint8 Saved_bWantsToSprint : 1;
|
||||
uint8 Saved_bWantsToSlide : 1;
|
||||
uint8 Saved_bWantsToAds : 1;
|
||||
uint8 Saved_bWantsToDash : 1;
|
||||
|
||||
uint8 Saved_bWantsToSlide:1;
|
||||
|
||||
uint8 Saved_bWantsToAds: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 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;
|
||||
};
|
||||
|
||||
|
@ -46,7 +59,7 @@ class NAKATOMI_API UNakatomiCMC : public UCharacterMovementComponent
|
|||
public:
|
||||
FNetworkPredictionData_Client_Nakatomi(const UCharacterMovementComponent& ClientMovement);
|
||||
|
||||
typedef FNetworkPredictionData_Client_Character Super;
|
||||
using Super = FNetworkPredictionData_Client_Character;
|
||||
|
||||
virtual FSavedMovePtr AllocateNewMove() override;
|
||||
};
|
||||
|
@ -75,20 +88,35 @@ class NAKATOMI_API UNakatomiCMC : public UCharacterMovementComponent
|
|||
UPROPERTY(EditDefaultsOnly)
|
||||
float Ads_Multiplier = 0.5f;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
float Dash_Impulse = 1500.0f;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
float Dash_CooldownDuration = 1.0f;
|
||||
|
||||
bool Safe_bWantsToSprint;
|
||||
bool Safe_bWantsToSlide;
|
||||
bool Safe_bWantsToAds;
|
||||
bool Safe_bWantsToDash;
|
||||
|
||||
float DashStartTime;
|
||||
FTimerHandle TimerHandle_DashCooldown;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
ANakatomiCharacter* NakatomiCharacterOwner;
|
||||
|
||||
public:
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FDashStartDelegate DashStartDelegate;
|
||||
|
||||
public:
|
||||
UNakatomiCMC();
|
||||
|
||||
protected:
|
||||
void InitializeComponent() override;
|
||||
virtual void InitializeComponent() override;
|
||||
|
||||
virtual FNetworkPredictionData_Client* GetPredictionData_Client() const override;
|
||||
|
||||
FNetworkPredictionData_Client* GetPredictionData_Client() const override;
|
||||
protected:
|
||||
virtual void UpdateFromCompressedFlags(uint8 Flags) override;
|
||||
|
||||
|
@ -127,16 +155,22 @@ public:
|
|||
UFUNCTION(BlueprintCallable)
|
||||
void DisableAds();
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void EnableDash();
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void DisableDash();
|
||||
|
||||
UFUNCTION()
|
||||
bool IsCustomMovementMode(ECustomMovementMove InCustomMovementMode) const;
|
||||
|
||||
private:
|
||||
|
||||
void EnterSlide();
|
||||
|
||||
void ExitSlide();
|
||||
|
||||
void PhysSlide(float deltaTime, int32 Iterations); // Every movement mode requires a physics function to work
|
||||
|
||||
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::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()
|
||||
{
|
||||
if (!IsFiring || CurrentWeapon->GetAmmoCount() == 0)
|
||||
|
|
|
@ -71,6 +71,9 @@ public:
|
|||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||
UInputAction* SlideAction;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||
UInputAction* DashAction;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||
TSoftObjectPtr<UInputMappingContext> InputMappingContext;
|
||||
|
||||
|
@ -186,6 +189,10 @@ public:
|
|||
|
||||
void EndSlideCallback(const FInputActionInstance& Instance);
|
||||
|
||||
void BeginDashCallback(const FInputActionInstance& Instance);
|
||||
|
||||
void EndDashCallback(const FInputActionInstance& Instance);
|
||||
|
||||
virtual void OnFire() override;
|
||||
|
||||
void WeaponCooldownHandler();
|
||||
|
|
Loading…
Reference in New Issue