适用于 Unity 的游戏玩法-能力-系统
该项目为Unreal Engine的Gameplay Ability System的Unity实现,目前实现了部分功能,后续会继续完善。
该项目完全开源,欢迎大家一起参与开发,提出建议,共同完善。可以基于该项目进行二次开发。
该项目依赖Odin Inspector插件(付费),请自行解决!!!!!!!!
Odin Inspector插件请使用3.2+版本
若没有方法解决,可以加反馈qq群(616570103),群内提供帮助
目前EX-GAS没有非常全面的测试,所以存在不可知的大量bug和性能问题。所以对于打算使用该插件的朋友请谨慎考虑,当然我是希望更多人用EX-GAS,毕竟相当于是变相的QA。
但是要讲良心嘛,现在的EX-GAS算不上很稳定的版本,如果你是业余时间开发rpg类的独立游戏,开发时间十分充裕,我当然建议你试试EX-GAS,我会尽可能修复bug,提供使用上的帮助。
如果有好兄弟确实打算用,那么请务必加反馈群(616570103)。我会尽力抽时间修复提出的bug。
我非常希望EX-GAS能早日稳定,为更多游戏提供支持帮助。
俯视角2D弹幕射击游戏
【国内镜像】https://gitee.com/exhard/gameplay-ability-system-for-unity.git?path=Assets/GAS
GAS十分复杂,使用门槛较高。因为本项目是对UE的GAS的模仿移植,所以实现逻辑基本一致。建议先粗略了解一下UE版本的GAS整体逻辑,参考项目文档:https://github.com/BillEliot/GASDocumentation_Chinese
在ProjectSetting中(或者Edit Menu栏入口:EX-GAS -> Setting),找到EX Gameplay Ability System的基本设置界面:
设置好以下两个路径
首次设置完路径后,点击检查子目录文件夹,确保必要的子文件夹都已生成。
【生成AbilitySystemComponentExtension类脚本】这个按钮,请在生成了Attribute,AttributeSet,Ability的Lib集合类之后再点击。特别提醒,AbilitySystemComponentExtension是工具类,理论上只生成一次即可。
配置Tag: Tag是GAS核心逻辑运作的依赖,非常重要。关于Tag的使用及运作逻辑详见章节(GameplayTag)
配置Attribute: Attribute是GAS运行时数据单位。关于Attribute的使用及运作逻辑详见章节(Attribute)
配置AttributeSet: AttributeSet是GAS运行时数据单位集合,合理的AttributeSet设计能够帮助程序解耦,提高开发效率。关于AttributeSet的使用及运作逻辑详见章节(AttributeSet)
设计MMC,Cue: 详见MMC, GameplayCue
设计Gameplay Effect: 详见 Gameplay Effect
设计Ability: 详见 Ability
设计ASC预设(可选): 详见 AbilitySystemComponent
EX-GAS是对UnrealEngine的GAS(Gameplay Ability System)的模仿和实现。
GAS 是 "Gameplay Ability System" 的缩写,是一套游戏能力系统。 这个系统的目的是为开发者提供一种灵活而强大的框架,用于实现和管理游戏中的各种角色能力、技能和效果。
如果把EX-GAS高度概括为一句话,那就是:WHO DO WHAT。
GAS本质是一套属性数值的管理系统,GameplayCue我个人理解为附加价值(虽然这个附加价值很有分量)。 纵使GAS的Tag体系解决复杂的GameplayEffect和Ability的逻辑,但最终的结果目的也只是掌握属性数值变化。 而属性的最底层修改权力交由了GameplayEffect。所以我把GE理解为结果。
UE的GAS的使用门槛很高,这一点在我构筑完EX-GAS雏形后更是深有体会。 所以在EX-GAS的设计上,我尽可能的做简化,优化,来降低了使用门槛。 我制作了几个关键的编辑器,来帮助开发者快速的使用EX-GAS。 但即便如此,GAS本身的繁多参数依然让编辑器的界面看上去十分臃肿,这很难简化,没有哪个参数是可以被删除的。 甚至,雏形阶段的EX-GAS还有很多功能还未实现,也就是说还有更多的参数是没有被编辑器暴露出来的。
GAS的使用者必须至少有一名程序开发人员,因为GAS的使用需要编写大量自定义业务逻辑。 Ability,Cue,MMC等都是必须根据游戏类型和内容玩法而定的。 非程序开发人员则需要完全理解EX-GAS的运作逻辑,才能更好的配合程序开发人员快速配置出各种各样的技能,完善玩法表现。
Gameplay Tag,标签,它用于分类和描述对象的状态,非常有用于控制游戏逻辑。
Gameplay Tag在GAS中的使用涉及到标签的添加、移除以及对标签变化的响应。 开发者可以通过GameplayTag Manager在项目设置中管理这些标签,无需手动编辑配置文件。 Gameplay Tag的灵活性和高效性使其成为GAS中控制游戏逻辑的重要工具。 它不仅可以用于简单的状态描述,还可以用于复杂的游戏逻辑和事件触发。
举个例子,GameplayEffect中有一个字段RequiredTags,其含义是当前GameplayEffect生效的AbilitySystemComponent(ASC) 需要拥有【所有】的RequiredTags(需求标签)。
上述例子,如果用传统的思路去做,可能需要写很多if-else判断,同时元素的实例脚本可能会增加很多状态标记的变量, 而且还需要考虑多个游戏效果的交互,这使得代码的设计和实现变得复杂,耦合。
GameplayTag的使用可以大大简化这些逻辑,使得代码更加清晰,易于维护。 他把状态和标记全部抽象成了一个独立的Tag系统,而且最巧妙的是树形结构的设计。 他解决了很多Gameplay设计上的问题,常见的问题比如:移除所有Debuff,传统的做法可能是让(中毒,减速,灼伤,等等)继承自Debuff类/接口; 而GameplayTag只需要添加一个Tag(中毒:Debuff.Poison,减速:Debuff.SpeedDown,灼伤:Debuff.Burning)
GameplayTag自身可以作为一个独立的系统去使用。 我在开发Demo的过程中就发现了GameplayTag的强大之处,他几乎替代了我的所有状态值。 甚至我设计了一个全局ASC,专门用来管理全局状态,我不需要对每个系统的状态管理,转而维护一个ASC即可。(虽然最后并没有落地这个设计,因为DEMO没有那么复杂。)
我模仿了UE的GAS的Tag管理视图,做了树结构管理。通过选中节点,可以添加子节点,删除节点。要修改父子级关系时,只需要拖动节点即可。 Tag的分类设计需要谨慎,策划(设计师)需要再项目初就规划好Tag的大致分类。如果开发后期出现了Tag的父子级关系大变动,会严重影响原有游戏运作逻辑。
【注意!!!】 每次编辑完Tag后,一定要点击右上角的【生成TagLib】按钮。GTagLib是包含了当前所有Tag的库类, 便于程序开发使用。GTagLib中Tag变量名会用‘_’代替‘.’ ,比如 State.Buff.PowerUp -> State_Buff_PowerUp
Attribute,属性,是GAS中的核心数据单位,用于描述角色的各种属性,如生命值,攻击力,防御力等。
Attribute和AttributeSet(属性集)需要结合起来才能作为唯一标识,简单点说AttributeSet是姓氏,Attribute是名字。 不同的AttributeSet可以有相同名字的Attribute,但是同一组的AttributeSet不可以有相同名字的Attribute。 常见的情况,如下:
AttributeSet 人物: 生命值, 法力, 攻击力, 防御力
AttributeSet 武器: 生命值(耐久度), 攻击力, 防御力
而这两组AttributeSet中的生命值,攻击力,防御力,都是不同的属性,他们的意义和作用不同。但他们可以属于同一个单位。
Attribute Manager的作用很简单,提供属性名字的管理。然后作为AttributeSet的选项使用。
【注意!!!】 每次编辑完Attribute后,一定要点击【生成AttrLib】按钮。 只有AttrLib生成后,AttributeSet的Attribute选项才会发生改变。
AttributeSet,属性集,是GAS中的核心数据单位集合,用于描述角色的某一类别的属性集合。
在上文的[2.3 Attribute]中,我们提到了AttributeSet是姓氏,Attribute是名字。二者结合起来才能作为唯一标识。 而对于AttributeSet的设计,可以较为随意,大多数情况,大家会更乐意一个单位只有一个AttributeSet。 因为这样便于管理和分类,不同类别的单位直接使用不同的AttributeSet。但实际上一个单位是可以拥有复数AttributeSet。 我其实比较认同一个单位只有一个AttributeSet的设计,因为这对程序开发也是好事,逻辑处理会更简单直白。
配置时的注意项:
AttributeSet Manager统筹属性集的命名和属性管理。
【注意!!!】 每次编辑完后,一定要点击【生成AttrSetLib】按钮。AttrSetLib会在AbilitySystemComponent的预设配置中用到。 AttrSetLib.gen.cs脚本中会包含所有的AttributeSet类(详见下文API章节),AttributeSet对应的类名是:“AS_名字”。 比如AttributeSet名字是Fight,那它对应的类名是AS_Fight。
ModifierMagnitudeCalculation,修改器,负责GAS中Attribute的数值计算逻辑。
MMC(下文开始会使用缩写指代ModifierMagnitudeCalculation)唯一的使用场景是在GameplayEffect中。 GAS中,体系内运作的情况下,只有GameplayEffect才能修改Attribute的数值。而GameplayEffect就是通过MMC修改Attribute的数值。
MMC具有以下特点:
MMC在GameplayEffect中的运作逻辑,结合GameplayEffect配置中MMC界面来解释。如下图:
MMC被存储在Modifier中,Modifier是GameplayEffect的一部分。 Modifier包含了修改的属性,幅值(Magnitude),操作类型和MMC。
ModifierMagnitude * k + b
实际上就是一个线性函数,k和b为可编辑参数,可以在编辑器中设置。AttributeValue * k + b
计算逻辑与ScalableFloatModCalculation一致。目前EX-GAS的GameplayCue功能还未完善。功能相对简陋。
第一条原则是所有类型游戏必须遵守的。
而第二条原则就见仁见智了,因为游戏类型和玩法决定了cue的影响范围。 比如即时战斗类游戏,cue对角色位移有操作显然就是干涉了战斗,但如果是回合制游戏,cue对角色位移的操作就可以被当成是动画表现。 (甚至,即便是即时战斗类游戏,cue对角色位移的操作也可以被当成是动画表现,只要游戏开发人员认为cue的位移操作不影响游戏的战斗结果即可。)
GameplayCueInstant和GameplayCueDurational都是抽象类,它们的子类才是真正的可使用Cue类。 Cue是需要程序开发人员大量实现的,毕竟游戏不同导致游戏提示千变万化。
| Spec类 | 需要实现的方法 | 方法触发时机 |
|---|---|---|
| GameplayCueInstantSpec |
瞬时性Cue的规格类|Trigger()| 执行时触发| |GameplayCueDurationalSpec 持续性Cue的规格类|OnAdd()| Cue被添加时触发| |GameplayCueDurationalSpec|OnRemove()| Cue被移除时触发| |GameplayCueDurationalSpec|OnGameplayEffectActivated()| Cue所属的GameplayEffect被激活时触发| |GameplayCueDurationalSpec|OnGameplayEffectDeactivated()| Cue所属的GameplayEffect被移除时触发| |GameplayCueDurationalSpec|OnTick()| Cue的每帧更新逻辑|
注意:customArguments是一个object数组,开发人员需要自己保证传递的参数类型正确,否则会导致运行时错误。 customArguments是最暴力的设计,往后EX-GAS的Cue参数传递设计还会进行优化。
| GameplayEffect类型 | Cue名称 | Cue类别 | 执行时机 |
|---|---|---|---|
| Instant | CueOnExecute | Instant | GameplayEffect执行时触发 |
| Durational | CueDurational | Durational | 生命周期完全和GameplayEffect同步 |
| Durational | CueOnAdd | Instant | GameplayEffect添加时触发 |
| Durational | CueOnRemove | Instant | GameplayEffect移除时触发 |
| Durational | CueOnActivate | Instant | GameplayEffect激活时触发 |
| Durational | CueOnDeactivate | Instant | G |
暂无开放 Issues,或尚未同步最近议题。