GAS - Gameplay Ability


GameplayAbility

Gameplay abilities是GAS中关于技能的抽象,可以非常傻瓜地实现法术,技能等等。除了可以实现冷却时间,技能消耗等其他RPG游戏中常见的施法机制外,还能自定义Ability Task来定制gameplay ability。这些tasks是在技能激活期间异步进行的,tasks中可以控制角色动画,粒子、声音效果等等,一旦任务完成或是接受到特定事件后,通过callback返回。Gameplay Ability支持replication。

举几个Abilities例子:

  • 等待一个动画播放完毕后释放火球魔法。
  • 按住按键吟唱火球魔法术,松开按键后发射火球。
  • 你甚至可以在释放火球前,让玩家玩DDR(跳舞机),根据玩家的手指舞蹈技术来决定火球魔法的强度。

Granting and Revoking Abilities(赋予和收回能力) [ Only on Server !!!]

赋予能力

在Actor可以使用Ability之前,Actor的Ability System Component需要被赋予能力。实现的方法为:

  • GiveAbilityAndActivateOnce: 赋予能力并尝试执行一次,在执行完成后,能力被收回(用得不多)
  • GiveAbility: 通过传入FGameplayAbilitySpec结构体,赋予能力,返回FGameplayAbilitySpecHandle(对于Ability的唯一标识)。Ability必须被实例化,并能在服务器上运行。在服务器上尝试运行Ability后,会返回FGameplayAbilitySpecHandle。如果Ability不满足标准,或者不能执行,则返回无效值。Ability System Component无法被赋予能力。
    RPGCharacterBase.cpp

    RPGCharacterBase.cpp

赋予能力时,其实传入的参数中有InputID,这涉及到Ability的输入绑定。你的能力总是要绑定到一个用户输入上吧,这样玩家才能施放能力。绑定的方式在后面在介绍Gameplay Ability Component的文中叙述。

赋予能力后需要调用InitAbilityActorInfo来配置Owner Actor和Avatar Actor,通常在PossessedBy函数中调用,应为更换Controller时,注册的信息(ActorInfo)会过时。

RPGCharacterBase.cpp

收回能力

使用之前的FGameplayAbilitySpecHandle(对于Ability的唯一标识)作为输入,可以移除指定Ability。

  • ClearAbility: 移除指定能力
  • SetRemoveAbilityOnEnd: 当能力执行完毕后,移除指定能力。如果能力不在执行中,则直接移除;若在执行中,则该能力的输入会被清空,玩家无法再激活或是和该能力交互。
  • ClearAllAbilities: 移除所有能力,不需要FGameplayAbilitySpecHandle。
    RPGCharacterBase.cpp

    RPGCharacterBase.cpp

Basic Usage(基本用法)

获得能力后,使用Ability的基本执行周期为:
1、 CanActivateAbility 让玩家在尝试使用能力之前知道是否可以激活该能力。比如,当能力不能激活是,UI图标变灰。
2、 CallActivateAbility 不检查能力是否可激活,直接调用能力。这个函数通常在CanActivateAbility和执行能力之间调用。

  • 玩家为实现自定义的Ability功能,主要的方式就是重写ActivateAbility方法,或是在蓝图中实现Activate Ability事件。
  • Gameplay Ability没有“tick”函数,而是通过Ability task异步执行。
  • Commit Ability函数在Activate Ability中调用,在这里应用执行能力的代价计算(如,蓝量,体力等资源的消耗,即Gameplay Attribute的减法,还有应用技能冷却等等)。
  • CancelAbility 提供机制以取消技能,CanBeCanceled可以拒绝这个函数执行。函数会调用OnGameplayAbilityCancelled,可以在此处做相关的清理。

3、TryActivateAbility 典型执行Ability的方法。会先调用CanActivateAbility进行检测,通过后调用CallActivateAbility
4、 EndAbility 结束Ability的执行。除了CancelAbility会自动调用该函数,其他情况下都要手动调用该函数或是在蓝图中添加End Ability节点来结束Ability的执行,否则会产生各种bug。

Melee Base Ability

Tags

Gameplay Tags用于Gameplay Abilties之间的相互交互。


Tag组中各个变量的作用

Gameplay Ability蓝图

除了Tags变量,还有其他由引擎提供的变量供配置,如:Costs,Cooldowns,Ability Trigger等等。

Advanced(高级)

https://docs.unrealengine.com/en-us/Gameplay/GameplayAbilitySystem/GameplayAbility

Replication

Gameplay Abilities支持内部状态的replication和Gameplay Event,也可以关闭replication节省资源。Gameplay Ability Replication Policy可以被设置为“Yes”或“No”来打开或关闭replication。还可以设置Gameplay Net Execution Policy控制Ability如何replicate。共有四种方式:

  • Local Predicted: 启用客户端预测,服务端可以回滚,可以减小延迟感。
  • Local Only: Ability只会在客户端运行,但改变的数值仍会replicate到服务端,也可以接受服务端的校正。
  • Server Initiated: Abilities由服务端初始化,然后通过网络传输到客户端,可以保证精确,但是可能会出现延迟感。
  • Server Only: Abilities只在服务端运行,数值会通过网络同步给客户端,客户端也仍能观察到能力视觉效果。

还未试验过,大家可以尝试看看不同方式的效果。

Instancing Policy(实例化策略)

每当Ability执行时,系统会生成一个新的该Ability类实例用以跟踪当前Ability的进展。但如果Ability使用频繁,或者存在大量的单位,则类的大量实例化会导致性能问题。引擎提供了三种策略来平衡性能问题。

  • Instanced per Execution: 每次执行Ability都会生成一个新的Ability对象。这种方法无疑是开销最大的。它的优势是你可以随意的使用蓝图和成员变量,所有的对象都会在执行能力前被初始化。这是最容易实现的实例化策略,适用于不频繁使用的Ability,比如具有长CD的技能。
  • Instance per Actor: 每个Actor在第一次执行Ability时,会生成该Ability的实例,之后重用这个对象。这就需要我们清理成员变量,并能保存每次执行的信息。这种方法是开销较小,在大规模的情况下也有不错的表现。
  • Non-Instanced: 最高效的策略。执行时不会生成任何实例,而是使用该类的Class Default Object。但这种方法存在一些限制。首先,无法使用蓝图Graph(需要Object Instance),只能使用C++。可以构建蓝图类,但是只能改变暴露的变量值。Ability执行中不能改变成员变量值,不能绑定delegate。不能replicate变量和处理RPCs。这种策略使用于不改变内部变量(可以修改Attributes),不需要replicate任何数据的Ability。特别适用于频繁被大量Actor使用的技能,如RTS或MOBA中的基本攻击。

Triggering with Gameplay Events

Gameplay Events是一个数据结构,可以直接触发Gameplay Abilities,与上文描述的使用ability方式不同,是另一条执行ability的方式。 通常使用Gameplay events的方法是调用Send Gameplay Event To Actor并提供实现了IAbilitySystemInterface的Actor,和所需要的上下文信息。也可以直接在Ability System Componet上处理Gameplay Event。
注意!
当Gameplay Ability由Gameplay Event触发时,Ability不会走Activate Ability这条路,而是使用Activate Ability From Event 并提供更多的上下文信息。如果在蓝图Graph中实现了Activate Ability From Event,则Activate Ability就不会再被执行了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容