GAS基础知识
GamePlayAbilitySystem:角色技能系统框架,虚幻自带的插件Plugins,默认是关闭的,使用时需要手动开启
健壮的、高度可扩展的gameplay框架,常用于构建RPG、MOBA等游戏的完整战斗逻辑框架,可以快速地制作游戏中的主动被动技能、各种效果Buff、计算属性伤害、处理玩家各种战斗逻辑
GAS提供的功能:
- 实现了带有消耗和冷却功能的角色技能
- 处理数值属性(生命、魔法、攻击力、防御力)
- 应用状态效果(击飞、着火、眩晕)
- 应用游戏标签(GameplayTags)
- 生成特效和音效
- 完整的网络复制、预测功能
使用GAS前提:
1、Unreal 编辑器中将GameplayAbilities插件勾选
2、VS中cs文件中加上"GameplayAbilities","GameplayTasks","GameplayTags"
3、VS中.uproject文件中Plugins加上
{
"Name": "GameplayAbilities",
"Enabled": true
}
功能概述:
AbilitySystemComponent:技能系统组件(GAS核心)。用于管理各种技能和处理技能系统的所有交互。该组件附加在需要拥有技能的角色上,并可以把技能赋予角色
本质为UActorComponent,用于处理整个框架下的交互逻辑,
包括使用技能(GameplayAbility)、包含属性(AttributeSet)、处理各种效果(GameplayEffect)
GameplayTags:游戏性标签,用于标记、描述Ability和Effect等游戏对象,相当于他们的ID。内部实现基于虚幻的FName字符串
是一种层级标签,如parent、child、grandchild通过GameplayTagManager进行注册
GameplayAbility(GA):技能。角色可以使用的能力,比如跳跃、攻击、火球术、次元斩等,创建不同的技能是GAS的主要工作。在GA中可以触发不同的技能任务(AbilityTask),它们承担了诸如播放动画、角色移动等持续一段时间的功能。
标识了游戏中一个对象(Actor)可以做的行为或技能,做某个动作的能力,对象同时可以激活多个GameplayAbility
GA的Class Defaults的重要设置:
- Ability Tags:可以说( so to speak )Gameplay Tags作为技能的标志使用,Gameplay Tags就是一个全局的名称和短语列表,可以用作资源的名称和标签。在GameplayAbilities的语境中,可以让一个GameplayAbility使用Ability Task来监听其他技能,这个技能拥有指定Tag作为技能Tag。
- 或者,一个技能A能够取消另一个拥有Tag X的处于激活状态的技能B,或者拥有Tag X的技能B处于激活状态时,技能A的激活会被阻挡。有很多简单的方法来设置技能间的全局行为和交互。
- Cancel Ability with Tags:拥有这些Tag的技能会在当前技能激活时被取消。
- Block Ability with Tags:拥有这些Tag的技能在当前技能激活的时候无法被激活。
- Activation Owned Tags:当技能激活的时候,所有者会获得这些Tag。这个和Ability Tags有所不同,因为所有者在这里获取这些Tag。GameplayEffects(buffs)能够与这些Tag交互,其他技能也可以,前面已经说过,监听所有者获得某个Tag的时候,激活技能。用法有很多种,取决于你的创造力,你可以让技能的使用在发动技能的时候免疫伤害,诸如此类。
- Activation RequiredTags:所有者必须拥有这些Tag技能才能够被激活。比如,清除负面buff的技能只有在你中了负面buff的时候才能被激活。
- Activation Blocked Tags:和Activation RequiredTags类似但是作用相反。技能的所有者必须没有这些Tag才能激活技能。对于群控效果来说是极好的,比如沉默,击晕,roots(某些游戏中,禁止移动相关的技能)。
- Source Required Tags:技能源(Source)必须拥有这些Tag。系统如何看待"Source Tags"并不是很明显,因为没有任何地方对它做出解释,不过你可以使用GameplayEvents特性,携带Payload来激活技能。GameplayEvent能够传递一个结构体,里面有一个InstigatorTags,可以用作Source Required和Source Blocked Tag的检测。当Payload包含所有指定的Tag,技能允许被激活。
- Source Blocked Tags:见Source Required Tags。Payload里包含这里指定的Tag,那么技能无法被激活。
- Target Required Tags:见Source Required Tags。同样的规则,只不过这里使用Payload结构体中的"TargetTags"。InstigatorTags应该使用技能所有者和触发者(通常是Character类)的描述性Tag来填充,然后TargetTags应该使用技能攻击目标的相关信息来填充。代码并没有强制你如何填充GameplayEvent数据中的Tag容器,你可以想咋整就咋整,这是真的。
- Target Blocked Tags:和Target Required Tags一样但是使用Blocked Tags。
- Cost GameplayEffect:这是一个GameplayEffect(某种意义上是一个buff,或直接改变属性的行为)可以包含一次性,或持久的属性修改器,比如说魔力和体力等等。GameplayEffect会检查它修改的属性值是否低于0,如果是的话,Commit Ability会通知Ability提前结束。
- Ability Triggers:可以用于远程激活技能。你可以选择激活技能作为对所有者获得某个Tag的响应(当所有者失去这个Tag时自动结束技能)。
- Cooldown GameplayEffect:这个GameplayEffect表示技能的冷却时间。当检测冷却时间时,技能会查看这个GamepalyEffect的Tag容器(在激活时它可以给予所有者这些Tag)并检测使用的Ability System是否获得了这些Tag。如果是的话,技能被视为正在冷却中。
- 本质上意味着所有独立的Cooldown GameplayEffect都需要专用的GameplayTag,同样也意味着多个技能之间可以很容易共享Cooldown GameplayEffect,
- 一个Cooldown GameplayEffect能够被设置为0或很小的值,这样能够在技能运行时通过指定的Tag来手动设置冷却时间,当你的技能没有一个能够预测和预定义的冷却时间时很有用。
GameplayEffect(GE):游戏性效果,相当于GAS中的Buff类,用于修改各种数值,一般通过改变自己或目标的属性值和标签(GameplayTag)来实现。比如附加伤害、回血、光环、Buff/Debuff等。技能的消耗和冷却通常也是用GE实现。
属性集AttributeSet是表示Actor各种属性值的集合,保存在ASC中,是GE的主要作用目标。
GE相当于一个可配置的数据表,不添加逻辑。创建一个UGameplayEffect的派生蓝图,就可以根据需求制作想要的效果
GE重要的变量(Notable Variables)
由于GameplayEffect蓝图类的反常性,它的数据要么是简单的值,其他类引用或仅仅是Tag。对于每种类型的Tag,都有三个Tag容器,其中一个(Combined Tags)不能直接编辑,Add表示在父类的基础上添加的Tag,Remove表示如果父类拥有这些Tag就移除它们。
- Duration Policy:技能时长类型。
- Instant:直接触发,永久修改目标属性。
- Has Duration:持续指定时间后自动结束。并且可以指定持续时间内效果触发的频率(Period属性)。
- Infinite:永久性的。
- Modifiers:属性能以各种形式改变(Add, Multply, Divide, Override,加,乘,除,覆盖)。
- Executions:Executions是个有趣的案例:它们本质上补足了GameplayEffect的功能(由于GameplayEffect尽量只存储数据的设计)。Execution带有一个GameplayEffectExecutionCalculation作为参数,这个类可以从Target和Source捕获属性,然后基于它们可以进行Modifier实现不了的复杂运算,比如伤害公式。只不过它们无法像GameplayAbility一样监听事件,而且它们也只会在GameplayEffect生命周期内有效。
- Stacking:你知道其他游戏里的buff/debuff是如何叠加的吗?这个行为可以在这里管理。默认情况下相同类型的GameplayEffect会独立进行计时。有选项可以让它们共享同一个计时器。当继续时间结束时移除一层栈,当计时器结束时移除所有的栈。
- Overflow:当爆栈时(当Stack数量达到Stack Limit Count的时候)触发的效果。当你足够冷的时候会冻僵,当吸入足够多的毒气的时候会深度中毒。
- Display:在这里可以使用GameplayCue。GameplayCue可以用来实现反映GameplayEffect的特效/音效。你也能够在GameplayAbility里直接调用GameplayCue。GameplayCue有良好的网络支持,可以让你为技能生成特效和音效让它更加炫酷。GameplayCue如何相应对它的调用是在有GameplayCue自己定义的(它可以相应4种类型的事件:OnActive(当GameplayCue激活以后调用),WhileActive(当GameplayCue被激活时调用),Removed(当GameplayCue被移除时调用。Executed(当GameplayEffect的执行类通过Instant或Has Duration方式运行时调用)。
- GrantedAbilities:这个有很多用途。你能够使用buff为目标提供一个临时的主动技能,比如火系法师让队友也拥有搓火球的能力?不过,更重要的是,你可以将这个特性用于需要持久运行,但是GameplayEffect Execution又无法做到的效果。比如,技能A会为Actor打上"OnFire" Tag,那么你可以使用一个Ice Buff,触发一个被动的Ice技能监听这个事件来消除"OnFire"效果和Ice Buff本身(GameplayAbility有一个函数能移除触发它的GameplayEffect)。结合Modifier和Execution一起使用几乎可以让你干任何事情。
要注意的一点是系统里使用的float并不是简单类型,而是通过FScalableFloat结构体封装的。你可以像简单类型float那样使用它,也能够使用Curve Table来为它指定值。
AttributeSet(AS):负责定义和持有属性,并管理属性的变化,包括网络同步
需要在Actor中被添加为成员变量,并注册到ASC(C++),一个ASC可以拥有多个AttributeSet
两个重要函数:
1、属性修改前回调:用于Attribute的currentValue被改变前调用,对应Infinite和Has Duration的GE
Virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)
2、GE执行后回调:用于Base Value改变后的调用,对应InstanceGE
Virtual void PostGameplayEffectExcute(const FGameplayEffectModCallBackData& Data) override
GameplayCue:游戏性提示,类似于GAS中的通知事件,用于触发外部事件,比如播放粒子特效、声音等
GA的Advanced属性
Replication:
- Local Predicted:GA会在客户端发出命令后,立即在客户端执行,但服务器拥有最终决定权。只要服务器不拒绝客户端的执行,整个过程将会顺畅执行。
- Local Only:客户端仅在本地运行Ability
- Server Initiated:服务器上发起的能力传播到客户端,客户端会有较小的延迟。如果对于快速执行的Ability,将不会像Local Predicted那样顺畅。
- Server Only:仅在服务端执行。但是Ability改变的变量都会复制到客户端,依然可以在客户端观察到产生的效果。
Instancing Policy:
- Instanced per Excution:每次执行都会实例化。对于冷却时间较长且使用人数较少的技能来说,可以使用该实例化策略。但不适用于冷却时间短且使用人数较多的技能,这样会导致大量的创建和复制。
- Instanced per Actor:每个Actor在第一次使用Ability时,会生成一个Ability实例,并可以重用它。
- Non-Instanced:该Ability在运行时不会产生任何实例,只是用类的默认对象。