PART 3 - 강의 4/4

Effect Stacking

GameplayEffect 스택 정책과 관리

01

Stacking Type

스택 집계 방식

EGameplayEffectStackingType UENUM() enum class EGameplayEffectStackingType : uint8 { // 스택 없음, 각각 독립 인스턴스로 적용 None, // 같은 소스에서 온 것만 스택 AggregateBySource, // 타겟 기준으로 스택 (가장 일반적) AggregateByTarget };
타입 동작 사용 예
None 독립 인스턴스 여러 소스의 DoT
AggregateBySource 소스별 스택 플레이어별 디버프
AggregateByTarget 타겟에 단일 스택 독 중첩, 출혈 스택
02

스택 정책 옵션

스택 동작 세부 설정

Blueprint 스택 설정 // GameplayEffect Blueprint에서 설정 // 1. Stack Limit Count // 최대 스택 수 (예: 5) // 2. Stack Duration Refresh Policy enum class EGameplayEffectStackingDurationPolicy : uint8 { RefreshOnSuccessfulApplication, // 스택 추가 시 지속시간 갱신 NeverRefresh // 지속시간 유지 }; // 3. Stack Period Reset Policy enum class EGameplayEffectStackingPeriodPolicy : uint8 { ResetOnSuccessfulApplication, // 주기 타이머 리셋 NeverReset // 주기 유지 }; // 4. Stack Expiration Policy enum class EGameplayEffectStackingExpirationPolicy : uint8 { ClearEntireStack, // 전체 스택 제거 RemoveSingleStackAndRefreshDuration, // 1스택 제거, 지속시간 갱신 RefreshDuration // 지속시간만 갱신 };
일반적인 스택 설정

독 디버프: AggregateByTarget, Stack Limit 5, RefreshOnSuccessfulApplication, ClearEntireStack

03

런타임 스택 조작

C++에서 스택 제어

스택 조작 예제 // 스택 카운트 지정하여 적용 void UMyAbility::ApplyStackingBuff() { FGameplayEffectSpecHandle SpecHandle = MakeOutgoingGameplayEffectSpec( StackingBuffEffectClass, GetAbilityLevel()); if (SpecHandle.IsValid()) { // 스택 카운트 설정 (기본값 1) SpecHandle.Data->SetStackCount(3); // 적용 ApplyGameplayEffectSpecToOwner(...); } } // 현재 스택 수 조회 int32 GetCurrentStackCount(UAbilitySystemComponent* ASC, TSubclassOf<UGameplayEffect> EffectClass) { FGameplayEffectQuery Query; Query.EffectDefinition = EffectClass; TArray<FActiveGameplayEffectHandle> Handles = ASC->GetActiveEffects(Query); if (Handles.Num() > 0) { const FActiveGameplayEffect* ActiveGE = ASC->GetActiveGameplayEffect(Handles[0]); if (ActiveGE) { return ActiveGE->Spec.GetStackCount(); } } return 0; }
04

스택 변경 이벤트

스택 변화 감지

스택 변경 델리게이트 void UMyComponent::ListenForStackChanges() { if (UAbilitySystemComponent* ASC = GetAbilitySystemComponent()) { // Effect 추가 시 ASC->OnActiveGameplayEffectAddedDelegateToSelf.AddUObject( this, &UMyComponent::OnGameplayEffectAdded); // Effect 제거 시 ASC->OnAnyGameplayEffectRemovedDelegate().AddUObject( this, &UMyComponent::OnGameplayEffectRemoved); } } void UMyComponent::OnGameplayEffectAdded( UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec, FActiveGameplayEffectHandle Handle) { // 특정 Effect인지 확인 if (Spec.Def->GetClass() == MyStackingEffectClass) { int32 NewStackCount = Spec.GetStackCount(); // UI 업데이트 등 } }
SUMMARY

핵심 요약

  • Stacking Type: None, AggregateBySource, AggregateByTarget
  • Stack Limit Count로 최대 스택 수 제한
  • Duration/Period/Expiration Policy로 세부 동작 제어
  • SetStackCount()로 런타임 스택 설정
  • 델리게이트로 스택 변경 이벤트 수신
PRACTICE

도전 과제

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

실습 1: GE 스태킹 설정

StackingType을 AggregateBySource/AggregateByTarget으로 각각 설정한 독 GE를 만들고, StackLimitCount, StackDurationRefreshPolicy를 테스트하세요.

실습 2: Overflow Effect

StackLimitCount 도달 시 OverflowEffects로 폭발 데미지를 발생시키는 시스템을 구현하세요. bDenyOverflowApplication으로 초과 스택을 거부하세요.

심화 과제

undefined