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
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
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));
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
205
206 if (UKnockbackComponent* KnockbackComponent = TargetCharacter->FindComponentByClass<UKnockbackComponent>())
207 {
208 KnockbackComponent->ApplyKnockback(KnockbackDirection, Payload.
KnockbackData);
209 return true;
210 }
211
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