堆叠策略处理 多个相同GameplayEffect 同时影响一个对象时的情景
GE_Poison只能与GE_Poison堆叠
不能和其复制类GE_Poison2堆叠 也不能和子类GE_Poison_Child堆叠
同类GE用CurveTable或SetByCaller设置不同的数值时
当有新的GE被施加时 会更新所有堆叠中的GE 与新GE一致 包括数值和持续时间
对于正在执行的那个GE 数值立即更新
若新GE的Duration比当前GE在类中设置的Duration更大 则更新 反之则 保留
堆叠的数值:
结合原码介绍GameEffect内部数值计算逻辑
堆叠的运行:
GE按照先后顺序依次执行 前一个GE的Duration跑完了 移除前一层GE 再轮到后一个GE
移除前一层GE之后 数值也会减少一层
堆叠的层数在Effect的Source对象上 不同对象上的堆叠不会相互影响
如果StackLimitCount为3 两个敌人向主角施加中毒Buff
那么每个敌人可以叠三层中毒Buff 主角能受到2*3层中毒Buff
但是不同敌人施加的Buff不会相互影响
堆叠的层数在Effect的Target对象上
如果StackLimitCount为3 两个敌人向主角施加中毒Buff
那么两个敌人一共可以叠三层Buff 主角只能受到3层中毒Buff
不同敌人施加的Buff会相互影响 (持续时间、伤害值)
堆叠的限制层数
新来的Effect应用成功时
当前这一层Effect已执行的时间归0 重新开始执行
更新当前GE的Duration为新GE的Duration
当前这一层已经执行的时间不刷新
新来的Effect成功应用时
当前这一层Effect这个周期已经执行的时间归0
之后以新来Effect的频率执行
如果Execute Periodic Effect on Application:为ture 则立即执行
如果Execute Periodic Effect on Application:为false 则等一个周期再执行
一直以第一个Effect的频率执行 直到所有Effect结束
当第一层效果过期时,移除整个堆叠的所有层数 终止GameplayEffect的执行
当第一层Effect过期之后 移除一层效果 然后第二层开始计时 以此类推
也就是说GE按照先后顺序依次执行 前一个GE的Duration跑完了 再轮到后一个GE
当一层Effect过期之后 不移除层数 然后刷新时间
这会导致效果一直持续下去 变为Infinite
你可以重写OnStackCountChange()回调函数实现自己的需求

当堆叠到最大层 继续施加GE时的策略
Overflow Effects:
当叠到最大层 继续施加GE时 触发其他的Effect
比如叠五层燃烧状态 然后发生爆炸
Deny Overflow Application:
当叠到最大层时 是否允许再叠
无论是否允许,尝试再去叠Effect时都会触发Overflow Effects
允许再叠的情况:
更新所有堆叠中的GE 与新GE一致 包括数值和持续时间
若新GE的Duration比当前GE的Duration更大 则更新 反之则 保留
Clear Stack on Overflow:
不允许再叠的情况:新GE不会影响数值和持续时间
若为true 一旦stack溢出 Effect层数就会被清空 强行终止GameplayEffect的执行
若为false stack满时不接受其他Effect 新GE不会产生任何影响

由于堆叠这个功能比较复杂
可以在ASC中重写OnGameplayEffectDurationChange回调函数
来测试GameplayEffect的持续时间
//MyAbilitySystemComponent.h
virtual void OnGameplayEffectDurationChange(struct FActiveGameplayEffect& ActiveEffect) override;
//MyAbilitySystemComponent.cpp
void UMyAbilitySystemComponent::OnGameplayEffectDurationChange(FActiveGameplayEffect& ActiveEffect)
{
//正在执行的GE的一些信息
ActiveEffect.StartWorldTime;
ActiveEffect.GetDuration();
ActiveEffect.GetTimeRemaining(GetWorld()->GetTimeSeconds());
}