0. 개요
크리티컬 확률, 크리티컬 데미지, 크리티컬 저항을 이용하여 데미지에 크리티컬 계산을 도입한다.
1. 크리티컬 계산
(1) 캡쳐할 속성 선언
// 단일 인스턴스 - 정적 구조체
struct AuraDamageStatics
{
// 속성에 대한 Def 생성
DECLARE_ATTRIBUTE_CAPTUREDEF(Armor);
DECLARE_ATTRIBUTE_CAPTUREDEF(ArmorPenetration);
DECLARE_ATTRIBUTE_CAPTUREDEF(BlockChance);
DECLARE_ATTRIBUTE_CAPTUREDEF(CriticalHitChance)
DECLARE_ATTRIBUTE_CAPTUREDEF(CriticalHitDamage)
DECLARE_ATTRIBUTE_CAPTUREDEF(CriticalHitResistance)
실행 계산에서 사용할(캡쳐할) 속성을 선언한다.
(2) 캡쳐할 속성 초기화
struct AuraDamageStatics
{
// 속성에 대한 Def 생성
DECLARE_ATTRIBUTE_CAPTUREDEF(Armor);
DECLARE_ATTRIBUTE_CAPTUREDEF(ArmorPenetration);
DECLARE_ATTRIBUTE_CAPTUREDEF(BlockChance);
DECLARE_ATTRIBUTE_CAPTUREDEF(CriticalHitChance)
DECLARE_ATTRIBUTE_CAPTUREDEF(CriticalHitDamage)
DECLARE_ATTRIBUTE_CAPTUREDEF(CriticalHitResistance)
AuraDamageStatics()
{
// 정적 클래스, 속성, 소스 or 타겟, 스냅샷 여부
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, Armor, Target, false);
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, ArmorPenetration, Source, false);
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, BlockChance, Target, false);
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, CriticalHitChance, Source, false);
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, CriticalHitDamage, Source, false);
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, CriticalHitResistance, Target, false);
}
};
캡쳐할 속성을 선언한 이후에 속성 세트를 참고하여 캡쳐할 속성을 초기화한다.
(3) 속성 매핑
UExecCalc_Damage::UExecCalc_Damage()
{
RelevantAttributesToCapture.Add(DamageStatics().ArmorDef);
RelevantAttributesToCapture.Add(DamageStatics().ArmorPenetrationDef);
RelevantAttributesToCapture.Add(DamageStatics().BlockChanceDef);
RelevantAttributesToCapture.Add(DamageStatics().CriticalHitChanceDef);
RelevantAttributesToCapture.Add(DamageStatics().CriticalHitDamageDef);
RelevantAttributesToCapture.Add(DamageStatics().CriticalHitResistanceDef);
}
생성자를 통해 캡쳐할 속성을 매핑한다.
(4) 계산
// 방어 데미지 계산
Damage *= (100 - EffectiveArmor * EffectiveArmorCoefficient) / 100.f;
// 크리티컬 확률, 크리티컬 데미지, 타겟 크리 저항
float SourceCriticalHitChance = 0.f;
float SourceCriticalHitDamage = 0.f;
float TargetCriticalHitResistance = 0.f;
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(DamageStatics().CriticalHitChanceDef, EvalParams, SourceCriticalHitChance);
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(DamageStatics().CriticalHitDamageDef, EvalParams, SourceCriticalHitDamage);
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(DamageStatics().CriticalHitResistanceDef, EvalParams, TargetCriticalHitResistance);
SourceCriticalHitChance = FMath::Max<float>(SourceCriticalHitChance, 0.f);
SourceCriticalHitDamage = FMath::Max<float>(SourceCriticalHitDamage, 0.f);
TargetCriticalHitResistance = FMath::Max<float>(TargetCriticalHitResistance, 0.f);
// 커브 테이블 - 크리티컬 저항 계수 가져오기
FRealCurve* CriticalHitResistanceCurve = CharacterClassInfo->DamageCalculationCoefficients->FindCurve(FName("CriticalHitResistance"), FString());
const float CriticalHitResistanceCoefficient = CriticalHitResistanceCurve->Eval(SourceCombatInterface->GetPlayerLevel());
// 최종 크리티컬
float FinalCriticalHitChance = SourceCriticalHitChance - (TargetCriticalHitResistance * CriticalHitResistanceCoefficient);
const bool bCriticalHit = FMath::RandRange(1, 100) < FinalCriticalHitChance;
// 크리티컬 발생 데미지
if (bCriticalHit)
{
Damage = (Damage * 2.f) + SourceCriticalHitDamage;
}
// 속성, 수정자, 속성 값
const FGameplayModifierEvaluatedData EvalData(UAuraAttributeSet::GetIncomingDamageAttribute(), EGameplayModOp::Additive, Damage);
OutexecutionOutput.AddOutputModifier(EvalData);
}
소스의 크리티컬 확률, 크리티컬 데미지를 가져오고 타겟의 크리티컬 저항을 가져온다.
데미지 계수 커브 테이블에서 크리티컬 저항 계수를 가져온다.
가져온 값을 이용하여 확률을 계산하고 데미지에 반영한다.
'UE 5 스터디 > Gameplay Ability System(GAS)' 카테고리의 다른 글
12-2. 게임플레이 이펙트 컨텍스트 - (2) 구조체 직렬화(Struct Ops Type Traits) (1) | 2024.12.24 |
---|---|
12-1. 게임플레이 이펙트 컨텍스트 - (1) 커스텀 게임플레이 이펙트 컨텍스트, 직렬화(Serialize) (0) | 2024.12.24 |
11-11. 데미지 실행 계산(Execution Calculation) - (3) 블록 확률, 방어력, 방어 관통 (0) | 2024.12.19 |
11-10. 데미지 실행 계산(Execution Calculation) - (2) 속성 캡쳐(Capturing Attributes) (0) | 2024.12.19 |
11-9. 게임플레이 이펙트 - (8) 실행 계산(Execution Calculation) (0) | 2024.12.19 |