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