13#include "TimerManager.h"
16#include "GameFramework/CharacterMovementComponent.h"
18static FORCEINLINE
float Clamp01(
float X){
return FMath::Clamp(
X, 0.f, 1.f); }
20UKnockbackSystem::UKnockbackSystem()
22 PrimaryComponentTick.bCanEverTick =
false;
25void UKnockbackSystem::BeginPlay()
30void UKnockbackSystem::EndPlay(
const EEndPlayReason::Type EndPlayReason)
33 GetWorld()->GetTimerManager().ClearTimer(FlyingTimer);
34 Super::EndPlay(EndPlayReason);
39 this->Owner = InOwner;
41 MeshComp = Owner->GetMesh();
42 MoveComp = Owner->GetCharacterMovement();
44 if (
auto EventManager = UBroadcastManager::Get(
this))
46 EventManager->OnKnockback.AddDynamic(
this, &UKnockbackSystem::OnKnockback);
50void UKnockbackSystem::OnKnockback( AActor* Target, AActor* Instigator,
EDamageType Type,
float Resistance)
52 if ( Owner != Target )
55 Knockback(Target, Instigator, Type, Resistance);
58FVector UKnockbackSystem::ComputeKnockDir(
const AActor* Target,
const AActor* Instigator)
60 FVector Dir = FVector::ZeroVector;
62 if (Target && Instigator)
63 Dir = Target->GetActorLocation() - Instigator->GetActorLocation();
69 FVector Fwd = Target->GetActorForwardVector();
70 Dir = (-Fwd).GetSafeNormal();
74 Dir = FVector::ForwardVector;
81void UKnockbackSystem::Knockback(AActor* Target, AActor* Instigator,
EDamageType Type,
float Resistance)
84 if (
auto DataManager = UGameDataManager::Get(GetWorld()))
86 if (!DataManager->GetKnockbackData(Type, Params))
90 const FVector Dir = ComputeKnockDir(Target, Instigator);
92 if (MoveComp->MovementMode != MOVE_Falling)
93 MoveComp->SetMovementMode(MOVE_Falling);
97 PrevBrakingFriction = MoveComp->BrakingFrictionFactor;
100 MoveComp->BrakingFrictionFactor = FMath::Clamp(Params.BrakingFrictionFactor, 0.f, 1.f);
102 const float Power = FMath::Max(0.f, Params.KnockbackPower) * (1.f -
Clamp01(Resistance));
104 FVector Launch = Dir * Power;
105 Launch.Z += Params.UpPower;
107 Owner->LaunchCharacter(Launch,
true,
true);
109 GetWorld()->GetTimerManager().SetTimer(
110 RestoreTimer,
this, &UKnockbackSystem::RestoreMovement,
111 FMath::Max(0.f, Params.Duration),
false
114 if (Params.bAfterFlying)
116 GetWorld()->GetTimerManager().ClearTimer(FlyingTimer);
117 GetWorld()->GetTimerManager().SetTimer(
118 FlyingTimer,
this, &UKnockbackSystem::EnterFlying,
119 FMath::Max(0.f, Params.FlyingDelay),
false
124void UKnockbackSystem::RestoreMovement()
128 MoveComp->BrakingFrictionFactor = PrevBrakingFriction;
133void UKnockbackSystem::EnterFlying()
Declares the player-controlled character actor.
FKnockbackData 구조체를 선언합니다.
UGameDataManager 클래스를 선언합니다.
static FORCEINLINE float Clamp01(float X)
UKnockbackSystem 클래스를 선언합니다.
Main character driven directly by the player.