KLingo Project Documentation 1.0.0
Unreal Engine 5.6 C++ Project Documentation
로딩중...
검색중...
일치하는것 없음
UKnockbackSystem.cpp
이 파일의 문서화 페이지로 가기
1// Copyright (c) 2025 Doppleddiggong. All rights reserved. Unauthorized copying, modification, or distribution of this file, via any medium is strictly prohibited. Proprietary and confidential.
2
8#include "UKnockbackSystem.h"
9
10#include "APlayerActor.h"
11#include "UGameDataManager.h"
12#include "FKnockbackData.h"
13#include "TimerManager.h"
14#include "UBroadcastManager.h"
15
16#include "GameFramework/CharacterMovementComponent.h"
17
18static FORCEINLINE float Clamp01(float X){ return FMath::Clamp(X, 0.f, 1.f); }
19
20UKnockbackSystem::UKnockbackSystem()
21{
22 PrimaryComponentTick.bCanEverTick = false;
23}
24
25void UKnockbackSystem::BeginPlay()
26{
27 Super::BeginPlay();
28}
29
30void UKnockbackSystem::EndPlay(const EEndPlayReason::Type EndPlayReason)
31{
32 RestoreMovement();
33 GetWorld()->GetTimerManager().ClearTimer(FlyingTimer);
34 Super::EndPlay(EndPlayReason);
35}
36
37void UKnockbackSystem::InitSystem(APlayerActor* InOwner)
38{
39 this->Owner = InOwner;
40
41 MeshComp = Owner->GetMesh();
42 MoveComp = Owner->GetCharacterMovement();
43
44 if (auto EventManager = UBroadcastManager::Get(this))
45 {
46 EventManager->OnKnockback.AddDynamic(this, &UKnockbackSystem::OnKnockback);
47 }
48}
49
50void UKnockbackSystem::OnKnockback( AActor* Target, AActor* Instigator, EDamageType Type, float Resistance)
51{
52 if ( Owner != Target )
53 return;
54
55 Knockback(Target, Instigator, Type, Resistance);
56}
57
58FVector UKnockbackSystem::ComputeKnockDir(const AActor* Target, const AActor* Instigator)
59{
60 FVector Dir = FVector::ZeroVector;
61
62 if (Target && Instigator)
63 Dir = Target->GetActorLocation() - Instigator->GetActorLocation();
64
65 if (!Dir.Normalize())
66 {
67 if (Target)
68 {
69 FVector Fwd = Target->GetActorForwardVector();
70 Dir = (-Fwd).GetSafeNormal();
71 }
72 else
73 {
74 Dir = FVector::ForwardVector;
75 }
76 }
77
78 return Dir;
79}
80
81void UKnockbackSystem::Knockback(AActor* Target, AActor* Instigator, EDamageType Type, float Resistance)
82{
83 FKnockbackData Params;
84 if (auto DataManager = UGameDataManager::Get(GetWorld()))
85 {
86 if (!DataManager->GetKnockbackData(Type, Params))
87 return;
88 }
89
90 const FVector Dir = ComputeKnockDir(Target, Instigator);
91
92 if (MoveComp->MovementMode != MOVE_Falling)
93 MoveComp->SetMovementMode(MOVE_Falling);
94
95 if (!bFriction)
96 {
97 PrevBrakingFriction = MoveComp->BrakingFrictionFactor;
98 bFriction = true;
99 }
100 MoveComp->BrakingFrictionFactor = FMath::Clamp(Params.BrakingFrictionFactor, 0.f, 1.f);
101
102 const float Power = FMath::Max(0.f, Params.KnockbackPower) * (1.f - Clamp01(Resistance));
103
104 FVector Launch = Dir * Power;
105 Launch.Z += Params.UpPower; // Always apply UpPower for testing
106
107 Owner->LaunchCharacter(Launch, true, true);
108
109 GetWorld()->GetTimerManager().SetTimer(
110 RestoreTimer, this, &UKnockbackSystem::RestoreMovement,
111 FMath::Max(0.f, Params.Duration), false
112 );
113
114 if (Params.bAfterFlying)
115 {
116 GetWorld()->GetTimerManager().ClearTimer(FlyingTimer);
117 GetWorld()->GetTimerManager().SetTimer(
118 FlyingTimer, this, &UKnockbackSystem::EnterFlying,
119 FMath::Max(0.f, Params.FlyingDelay), false
120 );
121 }
122}
123
124void UKnockbackSystem::RestoreMovement()
125{
126 if (bFriction)
127 {
128 MoveComp->BrakingFrictionFactor = PrevBrakingFriction;
129 bFriction = false;
130 }
131}
132
133void UKnockbackSystem::EnterFlying()
134{
135}
Declares the player-controlled character actor.
EDamageType
Definition EDamageType.h:9
FKnockbackData 구조체를 선언합니다.
UGameDataManager 클래스를 선언합니다.
static FORCEINLINE float Clamp01(float X)
UKnockbackSystem 클래스를 선언합니다.
Main character driven directly by the player.