PART 3 - 강의 3/4
Execution Calculation
가장 강력한 데미지 계산 시스템
01
Execution Calculation vs MMC
두 계산 방식의 차이점
| 특성 | MMC | Execution Calculation |
|---|---|---|
| 출력 | 단일 float | 다중 어트리뷰트 수정 |
| 예측 | 가능 | 불가능 |
| 용도 | 단순 계산 | 복잡한 데미지 공식 |
| 권장 | 클라이언트 즉시 반응 필요 시 | 서버 권위 데미지 |
Execution Calculation 예측 불가
Execution Calculation은 클라이언트 예측이 불가능합니다. 데미지 계산은 서버에서 수행하고 결과를 복제하는 것이 권장됩니다.
02
Execution Calculation 구현
데미지 공식 클래스 작성
Execution Calculation 클래스
UCLASS()
class UMyDamageExecution : public UGameplayEffectExecutionCalculation
{
GENERATED_BODY()
public:
UMyDamageExecution();
virtual void Execute_Implementation(
const FGameplayEffectCustomExecutionParameters& ExecutionParams,
FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const override;
private:
FGameplayEffectAttributeCaptureDefinition DamageDef;
FGameplayEffectAttributeCaptureDefinition ArmorDef;
};
UMyDamageExecution::UMyDamageExecution()
{
// 소스에서 BaseDamage 캡처
DamageDef.AttributeToCapture =
UCombatAttributeSet::GetBaseDamageAttribute();
DamageDef.AttributeSource =
EGameplayEffectAttributeCaptureSource::Source;
DamageDef.bSnapshot = true;
// 타겟에서 Armor 캡처
ArmorDef.AttributeToCapture =
UCombatAttributeSet::GetArmorAttribute();
ArmorDef.AttributeSource =
EGameplayEffectAttributeCaptureSource::Target;
ArmorDef.bSnapshot = false;
RelevantAttributesToCapture.Add(DamageDef);
RelevantAttributesToCapture.Add(ArmorDef);
}
Execute 구현
void UMyDamageExecution::Execute_Implementation(
const FGameplayEffectCustomExecutionParameters& ExecutionParams,
FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const
{
UAbilitySystemComponent* TargetASC =
ExecutionParams.GetTargetAbilitySystemComponent();
UAbilitySystemComponent* SourceASC =
ExecutionParams.GetSourceAbilitySystemComponent();
const FGameplayEffectSpec& Spec = ExecutionParams.GetOwningSpec();
// 태그 가져오기
const FGameplayTagContainer* SourceTags =
Spec.CapturedSourceTags.GetAggregatedTags();
const FGameplayTagContainer* TargetTags =
Spec.CapturedTargetTags.GetAggregatedTags();
FAggregatorEvaluateParameters EvaluationParameters;
EvaluationParameters.SourceTags = SourceTags;
EvaluationParameters.TargetTags = TargetTags;
// 어트리뷰트 값 가져오기
float BaseDamage = 0.f;
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(
DamageDef, EvaluationParameters, BaseDamage);
float Armor = 0.f;
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(
ArmorDef, EvaluationParameters, Armor);
// SetByCaller에서 추가 데미지
float BonusDamage = Spec.GetSetByCallerMagnitude(
FGameplayTag::RequestGameplayTag(FName("Data.Damage.Bonus")),
false, 0.f);
// 데미지 계산
float FinalDamage = BaseDamage + BonusDamage;
float DamageReduction = Armor / (Armor + 100.f);
FinalDamage *= (1.f - DamageReduction);
FinalDamage = FMath::Max(FinalDamage, 1.f);
// 출력 Modifier 추가
if (FinalDamage > 0.f)
{
OutExecutionOutput.AddOutputModifier(
FGameplayModifierEvaluatedData(
UHealthAttributeSet::GetDamageAttribute(),
EGameplayModOp::Additive,
FinalDamage
)
);
}
}
03
다중 출력 Modifier
여러 어트리뷰트 동시 수정
다중 출력 예제
// Execute에서 여러 어트리뷰트 동시 수정
void UMyExecution::Execute_Implementation(...) const
{
// 1. 데미지 적용
OutExecutionOutput.AddOutputModifier(
FGameplayModifierEvaluatedData(
UHealthAttributeSet::GetDamageAttribute(),
EGameplayModOp::Additive,
CalculatedDamage
)
);
// 2. 마나 흡수 (생명력 흡수 스킬)
float LifeSteal = CalculatedDamage * 0.1f;
OutExecutionOutput.AddOutputModifier(
FGameplayModifierEvaluatedData(
UHealthAttributeSet::GetHealingAttribute(),
EGameplayModOp::Additive,
LifeSteal
)
);
// 3. 분노 게이지 증가
OutExecutionOutput.AddOutputModifier(
FGameplayModifierEvaluatedData(
UResourceAttributeSet::GetRageAttribute(),
EGameplayModOp::Additive,
10.f
)
);
}
04
GameplayEffect에서 사용
Blueprint 설정
Blueprint 설정
// GameplayEffect Blueprint에서:
// 1. Executions 배열에 추가
// Calculation Class: MyDamageExecution
// 2. Conditional Gameplay Effects (선택)
// 조건부로 추가 Effect 적용
// 3. Modifiers는 비워둠
// Execution이 직접 어트리뷰트 수정
// 참고: Execution과 Modifier를 함께 사용 가능
// Modifier가 먼저 적용되고, Execution이 실행됨
Execution 사용 시기
복잡한 데미지 공식(방어력 감소, 속성 상성, 크리티컬 등)이 필요할 때 사용하세요. 단순 스탯 버프는 일반 Modifier로 충분합니다.
SUMMARY
핵심 요약
- Execution Calculation: 다중 어트리뷰트 수정 가능, 예측 불가
- MMC: 단일 값 반환, 예측 가능
- AttemptCalculateCapturedAttributeMagnitude()로 어트리뷰트 값 조회
- AddOutputModifier()로 여러 어트리뷰트 동시 수정
- 서버 권위 데미지 계산에 Execution Calculation 권장
PRACTICE
도전 과제
배운 내용을 직접 실습해보세요
실습 1: 기본 Execution Calculation
UGameplayEffectExecutionCalculation을 상속하여 소스 AttackPower와 타겟 Defense로 최종 데미지를 계산하세요. Execute에서 OutExecutionOutput.AddOutputModifier로 결과를 반환하세요.
실습 2: Capture 설정
FGameplayEffectAttributeCaptureDefinition으로 Source와 Target의 어트리뷰트를 각각 캡처하세요. AttemptCalculateCapturedAttributeMagnitude로 스냅샷 값을 읽어오세요.
심화 과제
undefined