GAS文档

 

Gameplay技能系统是一个高度灵活的框架,可用于构建你可能会在RPG或MOBA游戏中看到的技能和属性类型。你可以构建可供游戏中的角色使用的动作或被动技能,使这些动作导致各种属性累积或损耗的状态效果,实现约束这些动作使用的“冷却”计时器或资源消耗,更改技能等级及每个技能等级的技能效果,激活粒子或音效,等等。简单来说,此系统可帮助你在任何现代RPG或MOBA游戏中设计、实现及高效关联各种游戏中的技能,既包括跳跃等简单技能,也包括你喜欢的角色的复杂技能集。 – 官方文档

目录

  1. 介绍
  2. 概念
    2.1 Ability System Component
    2.2 标签 (Gameplay Tags)
    2.3 属性 (Attribute)
          2.3.1 定义
          2.3.2 BaseValue vs CurrentValue
          2.3.4 监听属性变化
    2.4 属性集 (Attribute Set)
          2.4.1 定义
    2.5 效果 (Gameplay Effects)
          2.5.1 定义
          2.5.2 应用效果
          2.5.3 移除效果
          2.5.4 修改器 (Modifiers)
          2.5.5 叠加效果 (Stacking)
          2.5.6 授予技能 (Granted Abilities)
          2.5.7 标签
          2.5.8 无敌 (Immunity)
          2.5.9 修改器值计算 (Modifier Magnitude Calculations)
          2.5.10 执行计算 (Execution Calculations)
          2.5.11 应用条件 (Application Requirement)
          2.5.12 效果容器 (Gameplay Effect Containers)
    2.6 技能 (Gameplay Abilities)
          2.6.1 定义
          2.6.2 绑定输入
          2.6.3 授予技能 (Granting Abilities)
          2.6.4 激活技能 (Activating Abilities)
          2.6.5 标签
          2.6.6 传入数据到技能
          2.6.7 消耗和冷却
    2.7 技能任务 (Ability Tasks)
          2.7.1 定义
          2.7.2 自定义技能任务
          2.7.3 根运动 (Root Motion Source)
    2.8 Gameplay Cues
          2.8.1 定义
          2.8.2 触发 (Trigger) Gameplay Cue
          2.8.3 Gameplay Cue参数
  3. 项目
    3.1 前缀
    3.2 目录
    3.3 输入
    3.4 标签
    3.5 角色蓝图
    3.6 动画通知
  4. 教程
    4.1 添加技能
    4.2 添加效果
    4.3 添加Gameplay Cue
    4.4 添加攻击技能
    4.5 添加受击反应
    4.6 添加眩晕
    4.7 添加英雄
    4.8 添加怪物
  5. 调试
    5.1 showdebug abilitysystem
    5.2 Gameplay Debugger
  6. 缩写
  7. 其他资源

1. 介绍

GameplayAbilitySystem是由Epic Games开发的UE4的插件,已经在Paragon和Fortnite两个内部3A项目中得到验证。

插件为游戏提供了开箱即用的解决方案:

:arrow_up_small: 回到顶部

2. 概念

章节

2.1 Ability System Component
2.2 Gameplay Tags
2.3 Attributes
2.4 Attribute Set
2.5 Gameplay Effects
2.6 Gameplay Abilities
2.7 Ability Tasks
2.8 Gameplay Cues

2.1 Ability System Component

AbilitySystemComponent(ASC)是GAS的核心组件,用于真正应用效果技能的组件。拥有属性的所有Actor都必须拥有该组件。

:arrow_up_small: 回到顶部

2.2 标签 (Gameplay Tags)

标签是祖.父.子形式的结构化字符串,标签可以用来归类或者描述对象的状态。比如当角色眩晕时,我们可以向它添加State.Stun标签。

标签存储在DefualtGameplayTags.ini文件中。可以通过项目设置中的标签分页来编辑标签,而不用手动修改文件。

gameplaytageditor.png

搜索引用的话会弹出熟悉的引用查看器窗口,显示引用该标签的所有资源。

:arrow_up_small: 回到顶部

2.3 属性 (Attributes)

2.3.1 定义

与游戏性技能系统交互的Actor通常需要具有一组数值属性,它们可供系统访问及修改,以影响游戏逻辑并跟踪游戏中发生的事件。它们可以表示任何事物,从角色的血量,到角色的等级,到子弹数量。任何属于Actor的数字,都可以考虑做成属性。属性只会被效果修改。

:arrow_up_small: 回到顶部

2.3.2 BaseValue vs CurrentValue

一个属性由两个数值组成 - BaseValueCurrentValueBaseValue代表属性的初始数值,而CurrentValueBaseValue经过效果修改后的值。举个栗子,假设角色拥有BaseValue为600的移动速度。如果没有任何效果修改移动速度,那么CurrentValue也是600。如果角色得到了一个+50的临时buff,那么BaseValue依然是600,但CurrentValue会变成650。如果buff过期,CurrentValue会恢复成600。

新手容易误以为BaseValue是属性的最大值,注意区分初始值和最大值的不同,最大值应该由单独的属性表示。

:arrow_up_small: 回到顶部

2.3.2 监听属性变化

项目提供了ListenForAttributeChange蓝图节点来监听属性的变化。 attributechange.png

:arrow_up_small: 回到顶部

2.4 属性集 (Attribute Set)

2.4.1 定义

属性集是属性的容器,其中定义了容器包含的属性。当前项目只定义了一个角色属性集,其中定义了如下属性:

属性 描述
Health 当前血量
MaxHealth 总血量
HealthRegenRate 血量回复速度(血量/秒)
Mana 当前魔法
MaxMana 总魔法
ManaRegenRate 魔法回复速度(魔法/秒)
Stamina 当前耐力
MaxStamina 总耐力
StrikeAttack 打击攻击
SlashAttack 斩击攻击
ThrustAttack 刺击攻击
StrikeDefense 打击防御
SlashDefense 斩击防御
ThrustDefense 刺击防御
StrikeResistance 打击抗性
SlashResistance 斩击抗性
ThrustResistance 刺击抗性
AttackPower 攻击力
DefensePower 防御力
MoveSpeed 移动速度(厘米/秒)
Damage 基础伤害

当前战斗公式为:伤害 = 基础伤害 * 攻击力 / 防御力

注意:属性集只能在代码中定义——不能在蓝图中定义。

:arrow_up_small: 回到顶部

2.5 效果 (Gameplay Effects)

2.5.1 定义

效果是技能改变属性标签的载体。它们可以制造瞬间的改变,比如伤害和治疗;也可以制造长时间的改变,比如加速和眩晕。

效果通过修改器执行计算来修改属性。

效果有三种持续类型:InstantDurationInfinite

效果还可以添加(Add)或执行(Execute)GameplayCues。一个Instant类型的效果会调用GameplayCueExecute函数,而DurationInfinite类型的效果调用GameplayCueAddRemove函数。

持续类型 函数 用途
Instant Execute 永久修改属性的BaseValue,不会应用标签。
Duration Add & Remove 临时修改属性的CurrentValue,并应用标签。在效果过期或移除后会回退所有修改。持续时间在效果蓝图中配置。
Infinite Add & Remove 临时修改属性的CurrentValue,并应用标签。这种效果永远不会过期,但可以通过技能来移除。

DurationInfinite的效果可以应用周期效果(Periodic Effects),即可以每隔Period秒应用一次它的修改器和执行计算。周期效果可以被视为Instant的效果。它们适合用于DOT类型的状态效果。

DurationInfinite的效果可以在应用后被临时地禁用和启用,如果Ongoing Tag Requirements没有满足就会禁用,反之就会启用。禁用会移除效果中的所有修改器和标签,但不会移除效果本身,启用后会重新加回这些修改器和标签。

:arrow_up_small: 回到顶部

2.5.2 应用效果

技能和ASC提供了一组函数来应用效果,这些函数以ApplyGameplayEffectTo的形式命名。

如果想要在技能外应用效果,比如子弹,需要拿到目标的ASC,然后调用其上的一个ApplyGameplayEffectToSelf函数。

:arrow_up_small: 回到顶部

2.5.3 移除效果

技能和ASC提供了一组函数来移除效果,这些函数以RemoveActiveGameplayEffect的形式命名。

如果想要在技能外移除效果,需要拿到目标的ASC,然后调用其上的一个RemoveActiveGameplayEffect函数。

:arrow_up_small: 回到顶部

2.5.4 修改器 (Modifiers)

修改器可以修改属性。一个效果可以拥有0到多个修改器,每个修改器只用一种操作符修改一种属性。

操作符 描述
Add 将参数与属性相加。使用负数来表示减法。
Multiply 将参数与属性相乘。
Divide 用属性除以参数。
Override 用参数覆盖属性。

CurrentValue = ((BaseValue + Additive) * Multiplicitive) / Division

Override会覆盖以上的值,实际的CurrentValue取决于等于最后一个Override

参数有四种类型:Scalable FloatAttribute BasedCustom Calculation ClassSet By Caller。每个最后都会生成一个浮点数,用于以上计算。

参数类型 描述
Scalable Float 等于系数乘以表中的值。表的列为等级,Scalable Floats会自动读取当前技能等级的值。如果没有表的话,表的值视为1。scalablefloats.png
Attribute Based 等于Coefficient * (Backing Attribute + Pre Multiply Additive Value) + Post Multiply Additive ValueBacking AttributeSource(谁创造了效果)或Target(谁接收了效果)中属性的CurrentValueBaseValueCurrentValue - BaseValueSnapshotting代表是否在创造效果时就捕捉属性的值,否则直到应用效果时才捕捉。
Custom Calculation Class Custom Calculation Class是最灵活的方式,它的值来自于专门编写的代码,而且可以被系数进一步操控。目前项目自定义了两个Custom Calculation Class,分别用来获取技能消耗和冷却时间。
Set By Caller 在创建效果时通过代码或蓝图手动指定的值。

:arrow_up_small: 回到顶部

2.5.5 叠加效果 (Stacking)

效果默认不叠加,只有DurationInfinite的效果才可以叠加。

叠加方式 (Stacking Type)有两种:Aggregate by SourceAggregate by Target

叠加方式 描述
Aggregate by Source 每个Source可以叠加Stack Limit Count个效果到Target
Aggregate by Target 所有Source一共可以叠加Stack Limit Count个效果到Target

其他选项的含义参见悬浮提示。

:arrow_up_small: 回到顶部

2.5.6 授予技能 (Granted Abilities)

效果可以向目标授予技能。只有DurationInfinite的效果可以授予技能。

击退可以用授予技能来实现,在授予的技能中移动目标,或者做任何我们想做的事。

参数中可以选择授予的技能,技能等级,技能关联的输入,和技能的移除策略。

移除策略 描述
Cancel Ability Immediately 随效果的移除而移除
Remove Ability on End 技能在执行完成后移除,不受效果影响
Do Nothing 不会移除,目标会一直拥有这个技能,直到某个时间点手动移除

:arrow_up_small: 回到顶部

2.5.7 标签

效果中带有很多标签,用以实现不同的逻辑。策划可以编辑Added GameplayTagsRemoved GameplayTags,结果会在Combined GameplayTags中显示。Added GameplayTags用来添加父类没有的标签,Removed GameplayTags用来移除父类的标签。父类是指效果蓝图的父类。

标签 描述
Gameplay Effect Asset Tags 效果内部的标签。没有任何功能,可以用来描述效果。
Granted Tags 效果内部的标签。会随着效果一起添加到目标身上,并在效果从目标身上移除时跟着移除。只对DurationInfinite的效果有效。
Ongoing Tag Requirements 在效果应用后,控制效果是否开启。如果目标身上的标签如果不满足这些条件,效果不会开启,当条件满足后效果会重新开启并应用它的修改器。只对DurationInfinite的效果有效。
Application Tag Requirements 效果的应用条件。如果目标身上的标签如果不满足这些条件,效果不会应用。
Remove Gameplay Effects with Tags 在效果成功应用后,任何Asset TagsGranted Tags中带有这些标签的效果都会从目标身上移除。

:arrow_up_small: 回到顶部

2.5.8 无敌 (Immunity)

效果可以使目标屏蔽某些效果的应用。

GrantedApplicationImmunityTags检查效果的源(也包括源技能上的AbilityTags)是否包含任何指定的标签,如果包含则阻止效果的应用。源是指效果的创建者。这种方式可以用来免疫特定角色或特定技能。

Granted Application Immunity Query检查效果是否与任何查询(Query)匹配以阻止或允许其应用。参数含义参见悬浮提示。

:arrow_up_small: 回到顶部

2.5.9 修改器值计算 (Modifier Magnitude Calculation)

修改器值计算用于修改器中,它唯一的目的就是返回一个浮点数。目前项目自定义了两个修改器值计算,RWBYMMC_Cost返回技能消耗,RWBYMMC_Cooldown返回技能冷却时间。

:arrow_up_small: 回到顶部

2.5.10 执行计算 (Execution Calculations)

执行计算可以理解为更强大的修改器,其逻辑是代码编写的。在遇到修改器解决不了的问题时,可以通过执行计算来解决。目前项目实现了一个名为RWBYExecCalc_Damage的执行计算,用来计算战斗公式。

:arrow_up_small: 回到顶部

2.5.11 应用条件 (Application Requirement)

应用条件可以用来实现更复杂的逻辑来判断效果是否可以应用,而不是简单的检查标签。只需在应用条件的蓝图中重载CanApplyGameplayEffect函数。

使用应用条件的例子:

  • 目标需要拥有特定数量的属性
  • 目标需要有特定层数的效果

应用条件还可以做更复杂的事情,比如检查效果是否已经在目标身上,或者改变既有效果的时间而不是应用新效果(在CanApplyGameplayEffect中返回false)。

:arrow_up_small: 回到顶部

2.5.12 效果容器 (Gameplay Effect Containers)

效果容器中包含一个目标类型(TargetType)和一组效果。

目标类型用来获取目标。当前项目定义了下列目标类型:

目标类型 描述
RWBYTargetType_UseOwner 使用源作为目标
RWBYTargetType_UseEventData 使用Event Data中的目标
TargetType_SphereTrace 做球型检测,将处于圆球范围的角色作为目标。圆球参数在目标类型的蓝图子类中配置。

技能提供了下列函数来应用效果容器:

函数 描述
MakeEffectContainerSpecFromContainer 为效果容器创建一个实例,实例可以在任意时间应用。典型的应用场景是将实例传递给子弹,在子弹命中时应用。
MakeEffectContainerSpec 在技能的Effect Container Map中查找标签对应的效果容器,为找的的效果容器创建一个实例,实例可以在任意时间应用。
ApplyEffectContainerSpec 应用实例。
ApplyEffectContainer 在技能的Effect Container Map中查找标签对应的效果容器,应用找到的效果容器。

:arrow_up_small: 回到顶部

2.6 技能 (Gameplay Abilities)

2.6.1 定义

技能是Actor可以执行的行为。同一时间可以执行多个技能,比如同时冲刺和射击。技能可以在C++或者蓝图中制作。

可以用技能实现的:

  • 冲刺
  • 射击
  • 每隔X秒格挡一次
  • 使用药水
  • 开门
  • 收集资源
  • 建造

不应该用技能实现的:

  • 基础移动
  • 与UI的交互

每个技能都带有一个等级。等级可以用来控制属性改变的值,或者改变技能的行为。

技能使用技能任务来执行持续一段时间的任务,比如等待事件、等待属性改变、等待玩家选择目标、使用跟运动移动角色。

所有的技能都需要重载ActivateAbility()函数来实现玩法。有些技能可能需要重载EndAbility()函数,EndAbility()在技能结束或取消时被调用。

一个简单技能的流程图:

abilityflowchartsimple.png

一个复杂技能的流程图:

abilityflowchartcomplex.png

复杂的技能可能由多个技能实现,技能之间互相激活、取消。

:arrow_up_small: 回到顶部

2.6.2 绑定输入

暂略,项目不会使用这一功能。

:arrow_up_small: 回到顶部

2.6.3 授予技能 (Granting Abilities)

技能需要先被授予才能被激活。项目角色类中有一个名为Gameplay Abilities的变量,用来配置那些需要在游戏开始时就被授予的技能。

:arrow_up_small: 回到顶部

2.6.4 激活技能 (Activating Abilities)

除了绑定输入外,ASC还提供了4种激活方式:标签、技能类、技能实例、事件。通过事件激活可以传入数据到技能中

想用事件激活技能,需要先配置好技能的触发器(Triggers)。为触发器分配一个标签然后在Trigger Source中选择Gameplay Event。然后使用SendGameplayEventToActor函数来发送事件,函数中的Playload参数存放想要传入的数据。

在触发器的Trigger Source中选择Owned Tag AddedOwned Tag Present,可以使技能在标签添加时激活,后者会还会使技能在标签移除时跟着移除。

注意:使用事件激活时,需要使用ActivateAbilityFromEvent节点,并且标准的ActivateAbility节点不能同时存在于蓝图中。如果ActivateAbility节点存在,它会屏蔽掉ActivateAbilityFromEvent节点,后者不会被调用。

注意:不要忘记调用EndAbility函数,除非技能需要一直运行,比如某些被动技能。

被动技能

被动技能在技能授予时自动激活。在Ability Tags中勾选Ability.Passive来将技能设定为被动技能。

:arrow_up_small: 回到顶部

2.6.5 标签

技能带有很多标签,用来实现不同的逻辑。

标签 描述
Ability Tags 技能拥有的标签。可以用来描述技能。
Cancel Abilities with Tag 当激活此技能时,Ability Tags中具有这些标签的其他技能将被取消。
Block Abilities with Tag 当此技能处于活动状态时,在其Ability Tags中具有这些标签的其他技能将被阻止激活。
Activation Owned Tags 当此技能处于活动状态时,这些标签会添加到ASC身上。
Activation Required Tags 仅当ASC拥有所有这些标签时,才能激活此技能。
Activation Blocked Tags 如果ASC拥有任何这些标签,则无法激活此技能。
Source Required Tags 仅当源具有所有这些标签时,才能激活此技能。源标签即事件Payload中的InstigatorTags,故仅当技能是由事件触发时才存在。
Source Blocked Tags 如果源具有这些标签中的任何一个,则不能激活此技能。
Target Required Tags 仅当目标具有所有这些标签时,才能激活此技能。目标标签即事件Payload中的TargetTags,故仅当技能是由事件触发时才存在。
Target Blocked Tags 如果目标具有这些标签中的任何一个,则不能激活此技能。

:arrow_up_small: 回到顶部

2.6.6 传入数据到技能

项目使用事件的Payload来传入数据到技能。Payload中的两个Optional Object变量可以用来传入不满足其他变量的数据。

:arrow_up_small: 回到顶部

2.6.7 消耗和冷却

技能带有可选的消耗和冷却。消耗是预定义好的某种属性数量。冷却是技能激活后再次激活需要的时间。

技能的消耗和冷却分别在Cost AmountCooldown Duration中配置。冷却还需要配置Cooldown Tag,每一个技能都应该有独特的CooldownTag

在技能调用ActivateAbility函数前,它会检查ASC是否可以支付消耗(CheckAbilityCost函数),以及技能是否已经冷却完成,只有都满足的情况下才会调用ActivateAbility函数。

ActivateAbility函数中我们可以在任意时间调用CommitAbility函数来提交消耗和冷却,提交的意思是扣除消耗和开始冷却计时。如果消耗和冷却不应该在同一时间提交的话,策划也可以选择分别调用CommitAbilityCostCommitAbilityCooldow来分别提交。在提交消耗和冷却时会再一次调用CheckAbilityCostCheckAbilityCooldown函数,失败的话返回false。

:arrow_up_small: 回到顶部

2.7 技能任务

2.7.1 定义

技能只会执行一帧,如果想要持续多帧或者响应晚些时候触发的事件,我们需要用到技能任务。

GAS带有如下技能任务:

  • 使用根运动(RootMotionSource)移动角色的任务
  • 播放蒙太奇的任务
  • 监听属性变化的任务
  • 监听效果变化的任务
  • 监听玩家输入的任务
  • 等等

:arrow_up_small: 回到顶部

2.7.2 自定义技能任务

项目自定义了如下技能任务:

  • PlayMontageAndWaitForEventPlayMontageAndWaitWaitGameplayEvent的结合。允许蒙太奇中的通知向技能发送事件,使用它来在动画的特定时间触发操作。
  • WaitReceiveDamage 暂略。

:arrow_up_small: 回到顶部

2.7.3 根运动 (Root Motion Source)

根运动技能任务可以用来移动角色,比如击飞、击退、跳跃和冲锋。

:arrow_up_small: 回到顶部

2.8 Gameplay Cues

2.8.1 定义

GameplayCue用于将标签绑定到粒子或声音资源。标签的开头必须是GameplayCue.,比如GameplayCue.A.B.C

我们通过标签来触发GameplayCue,标签会找到关联的GameplayCueNotify对象,并触发对象上的事件(ExecuteAddRemove)。

GameplayCueNotify对象共有两种,StaticActor。它们分别对应不同的事件和不同的效果

GameplayCueNotify 事件 效果 描述
GameplayCueNotify_Static Execute Instant/Periodic GameplayCueNotify_Static不会产生实例。它们适合一次性的表现,比如受击。
GameplayCueNotify_Actor Add/Remove Duration/Infinite GameplayCueNotify_Actor会在Add时创建实例,在Remove时销毁实例。它们适合循环的表现,比如眩晕,跟随效果一起添加和消除。

注意:当使用GameplayCueNotify_Actor时,不要忘记勾选Auto Destroy on Remove,否则后续的Add不会生效。

:arrow_up_small: 回到顶部

2.8.2 触发 (Trigger) Gameplay Cue

在效果中配置的GameplayCue会在效果成功应用后触发。

gcfromge.png

技能中提供了下列蓝图节点来触发GameplayCue

gcfromga.png

:arrow_up_small: 回到顶部

2.8.3 Gameplay Cue参数

GameplayCue会接收到一个FGameplayCueParameters类型的结构体作为参数,里面包含着额外的信息。如果GameplayCue是在技能中通过函数触发的,我们必须手动填写整个参数。如果GameplayCue是被效果触发的,效果会自动为我们填充参数中的如下变量:

  • AggregatedSourceTags
  • AggregatedTargetTags
  • GameplayEffectLevel
  • AbilityLevel
  • EffectContext
  • Magnitude (取决于效果中的Magnitude Attribute,暂略)

SourceObject可以用来传入自定义数据。

注意:有些变量,如Instigator,已经包含在EffectContext中了。EffectContext中还可以包含一个FHitResult,作为GameplayCue生成的位置。

:arrow_up_small: 回到顶部

3. 项目

3.1 前缀

前缀 资源类型
GA_ 技能
GC_ Gameplay Cue
GE_ 效果
AM_ 蒙太奇
A_ 动画序列
ABP_ 动画蓝图
BP_ 蓝图

完整命名规则参见UE4工程规范

:arrow_up_small: 回到顶部

3.2 目录

📦Content
 ┗ 📂RWBY
   ┗ 📂Characters
     ┣ 📂_Shared                   # 通用目录,存放角色间共享的资源
     ┃ ┣ 📂Abilities               # 战斗目录,存放技能、效果等战斗资源
     ┃ ┗ 📂AI                      # AI目录,存放黑板、装饰器、服务、任务等AI资源
     ┣ 📂_Temp                     # 临时目录,里面的内容可能在未来被删除
     ┗ 📂Beowolf                   # 每个角色有自己的目录
       ┣ 📂Abilities               # 战斗目录
       ┃ ┣ 📂GunShot               # 每个技能有自己的目录,包含技能相关的所有蓝图
       ┃ ┃ ┣ 📜BP_Projectile.uasset
       ┃ ┃ ┣ 📜GA_GunShot.uasset
       ┃ ┃ ┗ 📜GE_ProjectileDamage.uasset
       ┃ ┗ 📜GE_Attributes.uasset  # 属性效果,用于初始化属性
       ┣ 📂AI                      # AI目录
       ┣ 📂Animations              # 动画目录
       ┣ 📜ABP_Ruby.uasset         # 动画蓝图
       ┗ 📜BP_Ruby.uasset          # 角色蓝图

:arrow_up_small: 回到顶部

3.3 输入

当前项目的输入配置如下:

功能 键盘 XBOX
攻击 J B
闪避 K A
技能 U X
必杀技 I Y

:arrow_up_small: 回到顶部

3.4 标签

- Ability                       # 技能标签,用来描述技能,一个技能可能需要多个标签来描述
    - Melee                     # 近战技能
    - Ranged                    # 远程技能
    - Dodge                     # 闪避技能
    - Ultimate                  # 终结技能
    - Reaction                  # 反应技能
    - Passive                   # 被动技能
    - HitReaction               # 受击反应
    - NotCanceledByImbalance    # 不会被失衡状态取消
- GameplayCue                   # GameplayCue标签
    - Shared                    # 角色共享的GameplayCue
        - Stun
    - Ruby                      # 角色独有的GameplayCue
        - Attack
- GameplayEffect                # 效果标签,用来描述效果
- Event                         # 事件标签,用于SendEventToActor函数、Event通知或Damage通知
    - Trigger                   # 触发器事件
        - AbilityA
        - AbilityB
        - AbilityX
        - AbilityY
    - Montage                   # 蒙太奇事件
        - Shared                # 角色共享的蒙太奇事件
        - Ruby                  # 角色独有的蒙太奇事件
            - Attack
- Status                        # 角色状态标签,用来添加到角色身上,技能和效果都可以添加标签到角色
    - DamageImmune              # 免疫伤害
    - Dead                      # 死亡
    - Imbalance                 # 失衡

:arrow_up_small: 回到顶部

3.5 角色蓝图

项目约定了3种角色类型,每种有各自的基类:

类型 基类
英雄 BP_PlayerCharacter
敌人 BP_EnemyCharacter
NPC BP_NPCCharacter

所有的角色蓝图都包含以下变量:

  • Montages代表角色的受击动画。
  • Character Level代表角色的初始等级。
  • Gameplay Abilities代表角色拥有的技能,这些技能将在游戏开始时被授予。
  • Passive Gameplaly Effects代表角色的初始效果,这些效果会在游戏开始时就应用到角色身上。

:arrow_up_small: 回到顶部

3.6 动画通知

项目创建了下列通知来配合GAS:

  • Damage:制造伤害。参数为伤害形状和事件标签。技能在接收到事件后,会应用标签对应的效果容器。
  • Combo:连击。参数为要跳转的蒙太奇片段。持续时间内按下攻击的话会随机跳转一个片段。
  • ComboInput:连击预输入。持续时间内按下攻击的话,会在连击开始时随机跳转一个片段。
  • Event:向技能发送事件。参数为事件标签。
  • Hide:隐藏角色。
  • BlockAbilitiesWithTags:持续期间屏蔽Ability Tags中包含任意指定标签的技能。
  • MoveToCancel:持续期间移动的话打断Ability Tags中包含Ability.CanceledByMoveInput的技能。
  • BlockMoveInput:持续期间屏蔽玩家移动输入。
  • DisableCollision:持续期间关闭角色碰撞。
  • Slomo:慢动作。参数为慢放的倍数。
  • Death:延迟一段时间后销毁角色。可以放置于死亡动画中,在死亡动画完成后销毁角色。
  • PlayCameraAnim:播放相机动画。参数为相机动画的蓝图和相对坐标系。
  • PlayCameraShake:播放相机抖动。参数为相机抖动的蓝图和相对坐标系。

注意:以上通知仅作为DEMO阶段摸索的产物,正式项目时会重新设计。

:arrow_up_small: 回到顶部

4. 教程

4.1 添加技能

  1. 在内容浏览器中右键,选择Gameplay - Gameplay 能力蓝图。
  2. 根据自己的需要选择一个父类(默认建议选择RWBYGameplayAbility)。
  3. 编辑技能
    1. ActivateAbility中实现技能的逻辑,一般至少需要调用CommitAbility来提交消耗和冷却,和调用EndAbility来结束技能。
    2. Cost AmountCooldown Duration中配置消耗和冷却。
    3. 配置技能的标签,至少需要配置Ability Tags
    4. 英雄的技能还需要配置触发器,用来传入数据到技能,比如角色朝向。
  4. 将技能添加到角色蓝图的Gameplay Abilities中。

配置完成后就可以激活技能了。英雄的技能在角色蓝图中使用SendGameplayEventToActor函数来激活。怪物的技能在行为树中使用UseAbility任务来激活。

:arrow_up_small: 回到顶部

4.2 添加效果

  1. 在内容浏览器中右键,选择蓝图类。
  2. 输入并选择GameplayEffect
  3. 编辑效果
    1. 配置Duration PolicyPeriod
    2. 添加修改器或执行计算。
    3. 根据自己的需要配置其他内容。比如如果需要声音或特效表现就配置Gameplay Cues,如果需要动画和位移就配置Granted Abilities

配置完成后就可以应用效果了。

:arrow_up_small: 回到顶部

4.3 添加Gameplay Cue

  1. 在菜单栏的窗口中选择GameplayCue编辑器。
  2. 在新增Gameplay Cue标签中填写标签名,然后点击添加新标签。这一步也可以在项目设置的标签分页中操作。
  3. 在下方列表中找到新添加的标签,点击右侧新增按钮。
  4. 根据需要选择StaticActor,编辑器会在当前目录为我们创建一个GameplayCueNotify
  5. 编辑GameplayCueNotify
    1. 配置Gameplay Cue Tag,选择之前创建的标签。
    2. 覆盖事件函数来实现逻辑。
      • 如果是Static的话需要覆盖OnExecute函数,如果是Actor的话需要覆盖OnActiveOnRemoveWhileActive函数中的一到多个。
      • 调用SpawnEmitterAtLocationSpawnEmitterAttached来播放特效。调用SpawnSoundAtLocationSpawnSoundAttached来播放声音。
      • Actor可以不用调用函数来播放特效和声音。而是添加特效和声音组件,并勾选Auto Attach to Owner
    3. Actor不要忘记勾选Auto Destroy on Remove
    4. 根据自己的需要配置其他内容。

配置完成后就可以触发GameplayCue了。

:arrow_up_small: 回到顶部

4.4 添加攻击技能

下面展示如何为英雄添加一个攻击技能。假设这个攻击技能在按下XBOX的B键时触发,成功命中敌人后造成100点伤害并且播放受击特效和声音。

  1. 添加Gameplay Cue
    1. 选择Static类型。
    2. OnExecute函数中调用SpawnEmitterAttachedSpawnSoundAttached来播放特效和声音。
  2. 添加效果
    1. 配置Executionsaddge.png
    2. 在和Gameplay Cues中添加刚刚创建的Gameplay Cue
  3. 为攻击动画创建蒙太奇
    • 添加伤害通知,并配置伤害范围和伤害事件标签。
  4. 添加技能
    • 选择RWBYGameplayAbility作为父类。
    • 在技能的EffectContainerMap中添加刚刚创建的效果。
    • 覆盖ActivateAbilityFromEvent函数,播放蒙太奇并监听伤害事件。

    addga.png

    • 配置技能的标签和触发器。

    ga-tags-and-triggers.png

完成后在角色蓝图的Gameplay Abilities中添加技能,就可以使用XBOX的B键触发了。

:arrow_up_small: 回到顶部

4.5 添加受击反应

当前项目支持4种受击反应:叠加被击(HitAdditive)、被击(Hit)、击退(KnockBack)和击飞(KnockUp)。

  • 叠加被击可以通过在Gameplay Cue中调用PlayHitAdditive函数来实现。
  • 被击、击退和击飞可以通过在效果的授予技能中添加GA_HitGA_KnockBackGA_KnockUp来实现。

:arrow_up_small: 回到顶部

4.6 添加眩晕

  1. 添加一个Gameplay Cue
    • 选择Actor
    • 添加特效和声音组件,并勾选Auto Attach to Owner
  2. 添加一个效果
    • Duration Policy选择Has Duration,并在Duration Magnitude中配置眩晕时间。
    • Granted Tags中添加Status.Stun
    • Gameplay Cues中添加刚刚创建的Gameplay Cue

:arrow_up_small: 回到顶部

4.7 添加英雄

  1. 创建目录
    • Content/RWBY/Characters新建一个目录,用于存储该英雄所有的资源。
  2. 导入资源
    • 导入FBX到新创建的目录,导入后应当包括模型、骨骼和物理材质。
  3. 添加动画蓝图
    • 右键现有英雄的的动画蓝图。
    • 选择重定向动画蓝图,按下图配置后点击重定向。

    retarget-animbp.png (假设项目已经存在Ruby角色,现在正在添加White角色。)

  4. 添加属性效果
    • 创建Abilities目录,作为所有战斗资源的目录。
    • 可以复制一个现有的属性效果到Abilities目录,然后修改其中的参数。
  5. 添加角色蓝图
    1. 在新建的目录中右键,选择蓝图类。
    2. 输入并选择BP_PlayerCharacter
    3. 打开角色蓝图。
    4. 配置Mesh组件的Anim Class为新创建的动画蓝图,配置Mesh组件的Skeletal Mesh为导入的模型。
    5. Passive Gameplay Effects添加新创建的属性效果。
  6. 测试
    • 在项目设置的地图和模式分页中设置Default Pawn Class为新创建的角色,就可以在游戏中测试新角色了。

:arrow_up_small: 回到顶部

4.8 添加怪物

添加怪物与添加英雄类似,只是角色蓝图父类需要为BP_EnemyCharacter,动画蓝图需要使用怪物的动画蓝图来重定向,以及新增了一步 – 创建AI:

  1. 创建AI文件夹,用于存放所有AI资源。
  2. 创建黑板
    1. 在内容浏览器中右键,选择人工智能 - 黑板。
    2. 设置ParentBB_BaseBB_Base是所有怪物共享的黑板,需要共享的变量应当放到BB_Base中,角色黑板中只存放角色独有的变量。
  3. 创建行为树。
    1. 在内容浏览器中右键,选择人工智能 - 行为树。
    2. 设置Blackboard Asset为新创建的黑板。
  4. 创建AI Controller
    1. 在内容浏览器中右键,选择蓝图类。
    2. 输入并选择AI Controller
    3. Begin Play中调用Use BlackboardRun Behaviour Treeaicontroller.png
    4. 在角色蓝图的AI Controller Class中选择新创建的AI Controller

注意:你也可以复制现有怪物的AI黑板、行为树和AI Controller,记得在复制完成后修改ParentBlackboard AssetUse BlackboardRun Behaviour Tree到新创建的资源。

:arrow_up_small: 回到顶部

5. 调试

5.1 showdebug abilitysystem

暂略。

:arrow_up_small: 回到顶部

5.2 Gameplay Debugger

暂略。

:arrow_up_small: 回到顶部

6. 缩写

名称 缩写
AbilitySystemComponent ASC
AbilityTask AT
CharacterMovementComponent CMC
GameplayAbility GA
GameplayAbilitySystem GAS
GameplayCue GC
GameplayEffect GE
GameplayEffectExecutionCalculation ExecCalc, Execution
GameplayTag Tag, GT
ModiferMagnitudeCalculation ModMagCalc, MMC

7. 其他资源