Gameplay Effect Duration Policy

GameplayEffect Stacking
Stacking Type
None
Aggregate by Source

Aggregate by Target

Stack Limit Count
Stack Duration Refresh Policy / Stack Period Reset Policy
Stack Expiration Policy
Infinite Effect Removal
Duration이 Infinite로 지정된 GameplayEffect의 경우 별도로 제거를 해 주어야 함.
GameplayEffect를 제거하는 함수는 AbilitySystemComponent에서 제공하고 있음.
RemoveActiveGameplayEffect(FActiveGameplayEffectHandle, int32)
단, Infinite로 설정된 동일한 GameplayEffect가 여러 개 동시에 존재하고 있을 경우, 여러 액터들이 동일한 GameplayEffect에 의해 영향을 받고 있을 때 등의 상황들에 대한 조치를 해 주어야 제대로 제거할 수 있음.
// ApplyGameplayEffectSpecToSelf()는 FActiveGameplayEffectHandle을 반환함.
// RemoveGameplayEffect()로 GameplayEffect를 제거하기 위해서 FActiveGameplayEffectHandle에 대한 정보가 필요함.
// GameplayEffect를 적용받고 있는 액터들 또한 구분하기 위하여 TMap 변수를 생성하여 저장함.
// AuraEffectActor.h
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Applied Effect")
TMap<FActiveGameplayEffectHandle, UAbilitySystemComponent*> ActiveEffectHandles;
// AuraEffectActor.cpp
// ApplyEffectToTarget()
const FActiveGameplayEffectHandle ActiveEffectHandle = TargetASC->ApplyGameplayEffectSpecToSelf(*EffectSpecHandle.Data.Get());
const bool bIsInfinite = EffectSpecHandle.Data.Get()->Def.Get()->DurationPolicy == EGameplayEffectDurationType::Infinite;
if (bIsInfinite && InfiniteEffectRemovalPolicy == EEffectRemovalPolicy::RemoveOnEndOverlap)
{
// TMap 변수에 FActiveGameplayEffectHandle과 타겟 액터를 같이 담아둠.
ActiveEffectHandles.Add(ActiveEffectHandle, TargetASC);
}
// OnEndOverlap()
if (InfiniteEffectRemovalPolicy == EEffectRemovalPolicy::RemoveOnEndOverlap)
{
UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);
if (!IsValid(TargetASC)) return;
TArray<FActiveGameplayEffectHandle> HandlesToRemove;
// 액터의 AbilitySystemComponent를 확인하고 GameplayEffect를 1스택 제거
for (auto HandlePair : ActiveEffectHandles)
{
if (HandlePair.Value == TargetASC)
{
TargetASC->RemoveActiveGameplayEffect(HandlePair.Key, 1);
HandlesToRemove.Add(HandlePair.Key);
}
}
for (auto& Handle : HandlesToRemove)
{
ActiveEffectHandles.FindAndRemoveChecked(Handle);
}
}