Payback 0.0.1
CK Graduation Project
로딩중...
검색중...
일치하는것 없음
FCombatHitProcessor 클래스 참조

#include <CombatHitProcessor.h>

FCombatHitProcessor에 대한 협력 다이어그램:
Collaboration graph

정적 Public 멤버 함수

static FCombatHitApplyResult ApplyToTargetData (const FCombatHitPayload &Payload, const FGameplayAbilityTargetDataHandle &TargetDataHandle)
 
static FCombatHitApplyResult ApplyToActors (const FCombatHitPayload &Payload, const TArray< AActor * > &TargetActors, const FVector &ImpactOrigin)
 

정적 Private 멤버 함수

static bool ApplyToSingleTarget (const FCombatHitPayload &Payload, AActor *TargetActor, const FHitResult *OptionalHitResult, const FVector &KnockbackOrigin)
 
static bool ApplyKnockback (const FCombatHitPayload &Payload, AActor *TargetActor, const FVector &KnockbackOrigin)
 

상세한 설명

CombatHitPayload를 대상에게 적용하는 단일 창구입니다.

대상 검증 / GE 적용 / 넉백 규칙은 전부 이 클래스에만 존재합니다. 진입점이 둘인 이유는 적중 방식마다 보유한 정보가 다르기 때문입니다.

  • 트레이스 기반 적중은 실제 표면 충돌 결과를 가지고 있으므로 그대로 보존한다.
  • 광역 적중은 표면 정보가 없으므로 만들어내지 않는다.

멤버 함수 문서화

◆ ApplyKnockback()

bool FCombatHitProcessor::ApplyKnockback ( const FCombatHitPayload Payload,
AActor *  TargetActor,
const FVector &  KnockbackOrigin 
)
staticprivate
164{
165 ACharacter* TargetCharacter = Cast<ACharacter>(TargetActor);
166 if (IsValid(TargetCharacter) == false)
167 {
168 return false;
169 }
170
171 UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetCharacter);
172 if (IsValid(TargetASC) && TargetASC->HasMatchingGameplayTag(TAG_CHARACTER_STATE_ISSUPERARMOR))
173 {
174 return false;
175 }
176
177 AActor* SourceActor = Payload.SourceActor.Get();
178
179 FVector KnockbackDirection = TargetCharacter->GetActorLocation() - KnockbackOrigin;
180 KnockbackDirection.Z = 0.0f;
181
182 if (KnockbackDirection.IsNearlyZero())
183 {
184 KnockbackDirection = IsValid(SourceActor) ? SourceActor->GetActorForwardVector() : FVector::ForwardVector;
185 KnockbackDirection.Z = 0.0f;
186 }
187
188 KnockbackDirection = KnockbackDirection.GetSafeNormal();
189
190 if (Payload.KnockbackData.RotationCorrection > 0.0f && IsValid(SourceActor))
191 {
192 FVector SourceForward = SourceActor->GetActorForwardVector();
193 SourceForward.Z = 0.0f;
194 SourceForward = SourceForward.GetSafeNormal();
195
196 const float DotProduct = FMath::Clamp(FVector::DotProduct(KnockbackDirection, SourceForward), -1.0f, 1.0f);
197 const float AngleDegrees = FMath::RadiansToDegrees(FMath::Acos(DotProduct));
198 const float CorrectionDegrees = FMath::Min(Payload.KnockbackData.RotationCorrection, AngleDegrees);
199 const float CrossZ = KnockbackDirection.X * SourceForward.Y - KnockbackDirection.Y * SourceForward.X;
200 const float SignedCorrection = (CrossZ > 0.0f) ? CorrectionDegrees : -CorrectionDegrees;
201 KnockbackDirection = KnockbackDirection.RotateAngleAxis(SignedCorrection, FVector::UpVector);
202 }
203
204 KnockbackDirection.Z = Payload.KnockbackData.ZComponent;
205
206 if (UKnockbackComponent* KnockbackComponent = TargetCharacter->FindComponentByClass<UKnockbackComponent>())
207 {
208 KnockbackComponent->ApplyKnockback(KnockbackDirection, Payload.KnockbackData);
209 return true;
210 }
211
212 TargetCharacter->LaunchCharacter(KnockbackDirection * Payload.KnockbackData.Strength, true, true);
213 return true;
214}
FKnockbackData KnockbackData
Definition CombatHitPayload.h:19
TWeakObjectPtr< AActor > SourceActor
Definition CombatHitPayload.h:17
float Strength
Definition KnockbackData.h:17
float RotationCorrection
Definition KnockbackData.h:29
float ZComponent
Definition KnockbackData.h:25
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ ApplyToActors()

FCombatHitApplyResult FCombatHitProcessor::ApplyToActors ( const FCombatHitPayload Payload,
const TArray< AActor * > &  TargetActors,
const FVector &  ImpactOrigin 
)
static

표면 정보가 없는 광역 적중용. 넉백 기준점은 ImpactOrigin입니다.

69{
70 FCombatHitApplyResult ApplyResult;
71
72 if (Payload.IsValid() == false || TargetActors.IsEmpty())
73 {
74 return ApplyResult;
75 }
76
77 TSet<AActor*> AppliedActors;
78
79 for (AActor* TargetActor : TargetActors)
80 {
81 if (IsValid(TargetActor) == false)
82 {
83 continue;
84 }
85
86 bool bAlreadyApplied = false;
87 AppliedActors.Add(TargetActor, &bAlreadyApplied);
88 if (bAlreadyApplied)
89 {
90 continue;
91 }
92
93 // 광역 적중은 실제 표면 충돌 결과가 없으므로 HitResult를 넘기지 않는다.
94 if (ApplyToSingleTarget(Payload, TargetActor, nullptr, ImpactOrigin))
95 {
96 ApplyResult.AppliedTargetCount++;
97 }
98 }
99
100 if (ApplyResult.HasAppliedHit())
101 {
102 ApplyResult.FirstHitLocation = ImpactOrigin;
103 }
104
105 return ApplyResult;
106}
static bool ApplyToSingleTarget(const FCombatHitPayload &Payload, AActor *TargetActor, const FHitResult *OptionalHitResult, const FVector &KnockbackOrigin)
Definition CombatHitProcessor.cpp:109
Definition CombatHitProcessor.h:15
int32 AppliedTargetCount
Definition CombatHitProcessor.h:16
FVector FirstHitLocation
Definition CombatHitProcessor.h:17
FORCEINLINE bool HasAppliedHit() const
Definition CombatHitProcessor.h:19
bool IsValid() const
Definition CombatHitPayload.h:27
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ ApplyToSingleTarget()

bool FCombatHitProcessor::ApplyToSingleTarget ( const FCombatHitPayload Payload,
AActor *  TargetActor,
const FHitResult *  OptionalHitResult,
const FVector &  KnockbackOrigin 
)
staticprivate

OptionalHitResult가 nullptr이면 EffectContext에 적중 정보를 남기지 않습니다.

110{
111 if (TargetActor == Payload.SourceActor.Get())
112 {
113 return false;
114 }
115
116 UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);
117 if (IsValid(TargetASC) && TargetASC->HasMatchingGameplayTag(TAG_CHARACTER_STATE_ISDEAD))
118 {
119 return false;
120 }
121
122 UAbilitySystemComponent* SourceASC = Payload.SourceAbilitySystemComponent.Get();
123 bool bAppliedEffect = false;
124
125 for (const FGameplayEffectSpecHandle& EffectSpec : Payload.EffectSpecs)
126 {
127 if (IsValid(TargetASC) == false || EffectSpec.IsValid() == false)
128 {
129 continue;
130 }
131
132 // 대상마다 Context를 복제한다. 공유하면 적중 정보가 누적되어 다른 대상에게 섞인다.
133 FGameplayEffectSpec SpecToApply(*EffectSpec.Data.Get());
134 FGameplayEffectContextHandle EffectContext = SpecToApply.GetContext().Duplicate();
135 SpecToApply.SetContext(EffectContext);
136
137 if (OptionalHitResult != nullptr)
138 {
139 EffectContext.AddHitResult(*OptionalHitResult, true);
140 }
141
142 FActiveGameplayEffectHandle AppliedEffectHandle;
143 if (IsValid(SourceASC))
144 {
145 AppliedEffectHandle = SourceASC->ApplyGameplayEffectSpecToTarget(SpecToApply, TargetASC);
146 }
147 else
148 {
149 // 시전자가 이미 파괴된 뒤 도달한 비동기 적중. Spec은 완성되어 있으므로 대상이 직접 적용한다.
150 AppliedEffectHandle = TargetASC->ApplyGameplayEffectSpecToSelf(SpecToApply);
151 }
152
153 bAppliedEffect |= AppliedEffectHandle.WasSuccessfullyApplied();
154 }
155
156 // 넉백은 GE 적용 성공 여부와 무관하게 판단한다. (데미지 없는 순수 넉백 적중도 성립)
157 const bool bAppliedKnockback = Payload.bCauseKnockback ? ApplyKnockback(Payload, TargetActor, KnockbackOrigin) : false;
158
159 return bAppliedEffect || bAppliedKnockback;
160}
static bool ApplyKnockback(const FCombatHitPayload &Payload, AActor *TargetActor, const FVector &KnockbackOrigin)
Definition CombatHitProcessor.cpp:163
bool bCauseKnockback
Definition CombatHitPayload.h:20
TWeakObjectPtr< UAbilitySystemComponent > SourceAbilitySystemComponent
Definition CombatHitPayload.h:16
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ ApplyToTargetData()

FCombatHitApplyResult FCombatHitProcessor::ApplyToTargetData ( const FCombatHitPayload Payload,
const FGameplayAbilityTargetDataHandle &  TargetDataHandle 
)
static

트레이스 결과(FHitResult)를 보유한 적중용. 넉백 기준점은 Payload의 SourceActor 위치입니다.

16{
17 FCombatHitApplyResult ApplyResult;
18
19 if (Payload.IsValid() == false || TargetDataHandle.Data.IsEmpty())
20 {
21 return ApplyResult;
22 }
23
24 const AActor* SourceActor = Payload.SourceActor.Get();
25 const bool bHasSourceActor = IsValid(SourceActor);
26
27 TSet<AActor*> AppliedActors;
28
29 for (const TSharedPtr<FGameplayAbilityTargetData>& Data : TargetDataHandle.Data)
30 {
31 if (Data.IsValid() == false)
32 {
33 continue;
34 }
35
36 const FHitResult* HitResult = Data->GetHitResult();
37 AActor* TargetActor = (HitResult != nullptr) ? HitResult->GetActor() : nullptr;
38 if (IsValid(TargetActor) == false)
39 {
40 continue;
41 }
42
43 bool bAlreadyApplied = false;
44 AppliedActors.Add(TargetActor, &bAlreadyApplied);
45 if (bAlreadyApplied)
46 {
47 continue;
48 }
49
50 // 근접 계열은 시전자 위치를 기준으로 밀어낸다.
51 const FVector KnockbackOrigin = bHasSourceActor ? SourceActor->GetActorLocation() : TargetActor->GetActorLocation();
52
53 if (ApplyToSingleTarget(Payload, TargetActor, HitResult, KnockbackOrigin))
54 {
55 if (ApplyResult.AppliedTargetCount == 0)
56 {
57 ApplyResult.FirstHitLocation = HitResult->ImpactPoint.IsNearlyZero() ? HitResult->Location : HitResult->ImpactPoint;
58 }
59
60 ApplyResult.AppliedTargetCount++;
61 }
62 }
63
64 return ApplyResult;
65}
이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:
이 함수를 호출하는 함수들에 대한 그래프입니다.:

이 클래스에 대한 문서화 페이지는 다음의 파일들로부터 생성되었습니다.: