PART 2 - 강의 2/3

변경 콜백 체인

PreAttributeChange와 PostGameplayEffectExecute 활용

01

콜백 호출 순서

어트리뷰트 변경 시 콜백 체인

콜백 호출 순서 // GameplayEffect가 어트리뷰트를 수정할 때 호출 순서: 1. PreAttributeBaseChange() - Base 값이 변경되기 전에 호출 - 클램핑 가능 2. PreAttributeChange() - Current 값이 변경되기 전에 호출 - 클램핑 가능 (가장 많이 사용) 3. [실제 값 변경] 4. PostGameplayEffectExecute() - GameplayEffect 실행 완료 후 - 후처리 로직 (사망 체크 등) 5. OnRep_* (클라이언트만) - 서버에서 복제된 값 수신 시
02

PreAttributeChange

값 클램핑에 사용

PreAttributeChange 구현 void UMyAttributeSet::PreAttributeChange( const FGameplayAttribute& Attribute, float& NewValue) { Super::PreAttributeChange(Attribute, NewValue); // Health 클램핑: 0 ~ MaxHealth if (Attribute == GetHealthAttribute()) { NewValue = FMath::Clamp(NewValue, 0.0f, GetMaxHealth()); } // Mana 클램핑: 0 ~ MaxMana else if (Attribute == GetManaAttribute()) { NewValue = FMath::Clamp(NewValue, 0.0f, GetMaxMana()); } // 이동속도: 최소값 보장 else if (Attribute == GetMoveSpeedAttribute()) { NewValue = FMath::Max(NewValue, 100.0f); } }
CurrentValue만 영향

PreAttributeChange는 CurrentValue에만 영향을 줍니다. BaseValue 클램핑이 필요하면 PreAttributeBaseChange를 사용하세요.

03

PostGameplayEffectExecute

후처리 로직의 핵심

PostGameplayEffectExecute 구현 void UMyAttributeSet::PostGameplayEffectExecute( const FGameplayEffectModCallbackData& Data) { Super::PostGameplayEffectExecute(Data); // 소스와 타겟 정보 추출 FGameplayEffectContextHandle Context = Data.EffectSpec.GetContext(); UAbilitySystemComponent* SourceASC = Context.GetOriginalInstigatorAbilitySystemComponent(); AActor* SourceActor = Context.GetOriginalInstigator(); AActor* TargetActor = nullptr; if (Data.Target.AbilityActorInfo.IsValid()) { TargetActor = Data.Target.AbilityActorInfo->AvatarActor.Get(); } // Damage Meta Attribute 처리 if (Data.EvaluatedData.Attribute == GetDamageAttribute()) { const float LocalDamage = GetDamage(); SetDamage(0.f); // Meta Attribute 리셋 if (LocalDamage > 0.f) { // 실제 Health 감소 적용 const float NewHealth = GetHealth() - LocalDamage; SetHealth(FMath::Clamp(NewHealth, 0.0f, GetMaxHealth())); // 사망 체크 if (GetHealth() <= 0.f) { if (IMyCharacterInterface* CharInterface = Cast<IMyCharacterInterface>(TargetActor)) { CharInterface->OnDeath(SourceActor); } } } } }
PostGameplayEffectExecute 활용
  • Meta Attribute 처리 - Damage를 Health 감소로 변환
  • 사망 체크 - Health가 0 이하일 때 사망 이벤트
  • 추가 Effect 적용 - 조건부 버프/디버프
  • 통계 추적 - 총 받은 데미지 누적 등
04

FGameplayEffectModCallbackData

콜백에서 사용 가능한 정보

콜백 데이터 활용 void UMyAttributeSet::PostGameplayEffectExecute( const FGameplayEffectModCallbackData& Data) { // 변경된 어트리뷰트 FGameplayAttribute Attribute = Data.EvaluatedData.Attribute; // 계산된 크기 (Modifier Operation 적용 전) float Magnitude = Data.EvaluatedData.Magnitude; // Modifier Operation 타입 EGameplayModOp ModOp = Data.EvaluatedData.ModifierOp; // GameplayEffect Spec (SetByCaller 값 등) const FGameplayEffectSpec& Spec = Data.EffectSpec; // SetByCaller 값 가져오기 float BonusDamage = Spec.GetSetByCallerMagnitude( FGameplayTag::RequestGameplayTag(FName("Data.Damage.Bonus")), false, // WarnIfNotFound 0.f // DefaultValue ); // 타겟 ASC UAbilitySystemComponent* TargetASC = &Data.Target; }
SUMMARY

핵심 요약

  • 콜백 순서: PreAttributeBaseChange -> PreAttributeChange -> [변경] -> PostGameplayEffectExecute
  • PreAttributeChange: 값 클램핑에 사용 (CurrentValue)
  • PostGameplayEffectExecute: 후처리 로직 (사망 체크, Meta Attribute 처리)
  • FGameplayEffectModCallbackData: 소스/타겟, Effect Spec, SetByCaller 값 접근
  • Meta Attribute는 처리 후 반드시 0으로 리셋
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: PreAttributeChange 클램핑

PreAttributeChange()에서 Health를 0~MaxHealth로 클램핑하세요. MaxHealth 변경 시 현재 Health도 비율에 맞게 조정하는 로직을 구현하세요.

실습 2: PostGameplayEffectExecute 처리

PostGameplayEffectExecute()에서 Meta Attribute인 IncomingDamage를 받아 Health를 감소시키고, 0 이하 시 Dead GameplayTag를 추가하는 로직을 구현하세요.

심화 과제

undefined