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