虚幻引擎 GameplayAbilitySystem 基础概念03 ...

5

主题

10

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2022-11-30 16:38:03 | 显示全部楼层
前记:

很多翻译都是用的机器翻译不是很准确,我认真看了英文文档,再加上中文翻译做了该摘要,方便后来的学习者,也方便自己后续查阅。
字字不易,希望多多点赞收藏。也希望多多提意见
正文:

1、GameplayEffect(GE)是Ability修改其自身和其他Attribute和GameplayTag的容器;
2、UGameplayEffect只是一个定义单一游戏效果的数据类, 不应该在其中添加额外的逻辑;
3、GameplayEffect通过Modifier和Execution(GameplayEffectExecutionCalculation)修改Attribute;
4、即刻(Instant)GameplayEffect可以调用GameplayCue GameplayTag的Execute而持续(Duration)或无限(Infinite)可以调用GameplayCue GameplayTag的Add和Remove;
5、持续(Duration)和无限(Infinite)GameplayEffect可以选择应用周期性的Effect, 其每过X秒(由周期定义)就应用一次Modifier和Execution, 当周期性的Effect修改Attribute的BaseValue和执行GameplayCue时就被视为即刻(Instant)GameplayEffect,周期性的Effect不能被预测;
6、持续(Duration)和无限(Infinite)GameplayEffect的Ongoing Tag Requirements未满足/满足的话(Gameplay Effect Tags), 那么它们在应用后就可以被暂时的关闭和打开, 关闭GameplayEffect会移除其Modifier和已应用GameplayTag效果, 但是不会移除该GameplayEffect, 重新打开GameplayEffect会重新应用其Modifier和GameplayTag;
7、GameplayEffect一般是不实例化的, 当Ability或ASC想要应用GameplayEffect时, 其会从GameplayEffect的ClassDefaultObject创建一个GameplayEffectSpec;
8、 GameplayEffect可以被GameplayAbility和ASC中的多个函数应用, 其通常是ApplyGameplayEffectTo的形式, 不同的函数本质上都是最终在目标上调用UAbilitySystemComponent::ApplyGameplayEffectSpecToSelf()的方便函数;
9、你可以绑定持续(Duration)或无限(Infinite)GameplayEffect的委托来监听其应用到ASC
AbilitySystemComponent->OnActiveGameplayEffectAddedDelegateToSelf.AddUObject(this, &APACharacterBase::OnActiveGameplayEffectAddedCallback);
回调函数:
virtual void OnActiveGameplayEffectAddedCallback(UAbilitySystemComponent* Target, const FGameplayEffectSpec& SpecApplied, FActiveGameplayEffectHandle ActiveHandle);
服务端总是会调用该函数而不管同步模式是什么,Autonomous Proxy只会在Full和Mixed同步模式下对于同步的GameplayEffect调用该函数,Simulated Proxy只会在Full同步模式下调用该函数.
10、Modifier可以修改Attribute并且是唯一可以预测性修改Attribute的方法. 一个GameplayEffect可以有0个或多个Modifier, 每个Modifier通过某个指定的操作只能修改一个Attribute;
11、Attribute的CurrentValue是其所有Modifier与其BaseValue计算并总合后的结果,定义在GameplayEffectAggregator.cpp中的FAggregatorModChannel::EvaluateWithBase:((InlineBaseValue + Additive) * Multiplicitive) / Division
OverrideModifier会优先覆盖最后应用的Modifier得出的最终值.

12、默认情况下, 所有的Multiply和DivideModifier在对Attribute的BaseValue乘除前都会先加到一起;
13、Multiply和DivideModifier很复杂,设计比较另类需要注意
14、GameplayEffect可以设置到Stack中, 新的GameplayEffectSpec实例不会添加到Stack中, 而是修改当前已经存在的GameplayEffectSpecStack的层数. Stack只适用于持续(Duration)和无限(Infinite)GameplayEffect.
有两种类型的Stack: Aggregate by Source和Aggregate by Target.
15、GameplayEffect可以授予(Grant)新的GameplayAbility到ASC. 只有持续(Duration)和无限(Infinite)GameplayEffect可以授予Ability.
一个普遍用法是当想要强制另一个玩家做某些事的时候, 像击退或拉取时移动他们, 就会对它们应用一个GameplayEffect来授予其一个自动激活的Ability, 从而使其做出相应的动作
16、GameplayEffect可以带有多个GameplayTagContainer;Added标签是该GameplayEffect新增的之前其父类没有的标签,Removed标签是其父类拥有但该类没有的标签;
17、Ongoing Tag Requirements:一旦GameplayEffect应用后, 这些标签将决定GameplayEffect是开启还是关闭.GameplayEffect可以是关闭但仍然是应用的. 如果某个GameplayEffect由于不符合Ongoing Tag Requirements而关闭, 但是之后又满足需求了, 那么该GameplayEffect会重新打开并重新应用它的Modifier. 该标签只作用于持续(Duration)和无限(Infinite)GameplayEffect;
18、Application Tag Requirements:决定某个GameplayEffect是否可以应用到该目标的标签, 如果不满足这些需求, 那么GameplayEffect就不可应用;
19、Remove Gameplay Effects with Tags:当GameplayEffect成功应用后, 如果位于目标上的该GameplayEffect在其Asset Tags或Granted Tags中有任意一个本标签的话, 其就会自目标上移除.
20、GameplayEffectSpec(GESpec)可以看作是GameplayEffect的实例, 它保存了一个其所代表的GameplayEffect类引用;
21、GameplayEffectSpec不必立即应用. 通常是将GameplayEffectSpec传递给创建自Ability的投掷物, 该投掷物可以应用到它之后击中的目标. 当GameplayEffectSpec成功应用后, 就会返回一个名为FActiveGameplayEffect的新结构体.
22、ModifierMagnitudeCalculations(ModMagcCalc或MMC)是在GameplayEffect中作为Modifier使用的强有力的类, 它的功能类似GameplayEffectExecutionCalculation但是要逊色一些, 最重要的是它是可预测的;
23、MMC的优势在于能够完全访问GameplayEffectSpec来读取GameplayTag和SetByCaller,从而能够捕获GameplayEffect的源(Source)或目标(Target)上任意数量的Attribute值.
24、Attribute可以被Snapshot也可以不被Snapshot,Snapshotted Attribute在GameplayEffectSpec创建时被捕获而非Snapshotted Attribute在GameplayEffectSpec应用时被捕获并且该Attribute被无限(Infinite)或持续(Duration)GameplayEffect修改时会自动更新;
25、ExecutionCalculation只能由即刻(Instant)和周期性(Periodic)GameplayEffect使用, 插件中所有和"Execute"相关的一般都引用到这两种类型的GameplayEffect;
26、对于Local Predicted,Server Only和Server Initiated的GameplayAbility,ExecCalc只在服务端调用.
27、ExecCalc最普遍的应用场景是计算一个来自很多源(Source)和目标(Target)中Attribute伤害值的复杂公式. 样例项目中有一个简单的ExecCalc用于计算伤害值, 其从GameplayEffectSpec的SetByCaller中读取伤害值, 之后基于从目标(Target)捕获的护盾Attribute来减少该伤害值;
28、CustomApplicationRequirement(CAR)类为设计师提供对于GameplayEffect是否可以应用的高阶控制, 而不是对GameplayEffect进行简单的GameplayTag检查. 这可以通过在蓝图中重写CanApplyGameplayEffect()和在C++中重写CanApplyGameplayEffect_Implementation()实现.
29、默认情况下,Cost GE是可以被预测的, 建议保留该功能, 也就是不要ExecutionCalculations,MMC对于复杂的花费计算是完美适配并且鼓励使用的;
30、一个更高阶的技巧是对多个GA复用一个Cost GE, 只需修改自GA的Cost GE创建的GameplayEffectSpec中指定的数据(花费值是在GA上定义的),这只作用于实例化(Instanced)的Ability.
31、GA实际上会检查Cooldown Tag的存在而不是Cooldown GE的存在, 默认情况下,Cooldown GE是可以被预测的, 建议保留该功能, 也就是不要使用ExecutionCalculations,MMC对于复杂的冷却计算是完美适配并且鼓励使用的;
32、一个更高阶的技巧是对多个GA复用一个Cooldown GE, 只需修改自GA的Cooldown GE创建的GameplayEffectSpec中指定的数据(冷却时间和Cooldown Tag是在GA上定义的),这只作用于实例化(Instanced)的Ability.
33、在客户端上查询剩余冷却时间要求其可以接收同步的GameplayEffect, 这依赖于它们ASC的同步模式.
34、建议监听Cooldown GE何时应用, 因为这时还可以访问应用它的GameplayEffectSpec. 由此你可以确定当前Cooldown GE是客户端预测的还是由服务端校正的.
35、建议监听Cooldown Tag何时移除, 因为当服务端校正的Cooldown GE到来时, 会移除客户端预测的Cooldown GE, 这会响应OnAnyGameplayEffectRemovedDelegate(), 即使仍处于冷却过程中. 预测的Cooldown GE在移除时和服务端校正的Cooldown GE在应用时Cooldown Tag都不会改变.
36、在客户端上监听某个GameplayEffect添加或移除要求其可以接收同步的GameplayEffect, 这依赖于它们ASC的同步模式;
37、目前冷却时间不是真正可预测的. 我们可以在客户端预测的Cooldown GE应用时启动UI的冷却时间计时器, 但是GameplayAbility的实际冷却时间是由服务端的冷却时间剩余决定的. 取决于玩家的延迟情况, 可能客户端预测的冷却已经结束, 但是服务端上的GameplayAbility仍处于冷却过程, 这会阻止GameplayAbility的立刻再激活直到服务端冷却结束.
38、Epic希望在未来的GAS迭代版本中实现真正的冷却预测(玩家可以激活一个在客户端冷却完成但服务端仍处于冷却过程的GameplayAbility);
39、只有即刻(Instant)GameplayEffect可以在运行时由C++创建,持续(Duration)和无限(Infinite)GameplayEffect不能在运行时动态创建, 因为它们在同步时会寻找并不存在的GameplayEffect类定义;
回复

举报 使用道具

您需要登录后才可以回帖 登录 | 立即注册
快速回复 返回顶部 返回列表