系列文章目录
待完成…
文章目录
(4) Gameplay Tags
⓪.什么是GT
GT(Gameplay Tags )在GAS中是必不可少的,GT不仅存在于GAS中它们也存在于GAS之外,可以用于非GAS的项目,在非GAS项目中我们也广泛使用
- GT的核心实际上就是FName
- 它们有GT的类(FGameplayTag),并且注册在游戏玩法标签管理器中(Gameplay Tag Manager)
![[image-20240719215633265.png]]
- GT具有层级性质,层级之间采用父-子-孙的形式,每一层级都由一个点分隔
- 层级可以多也可以少
![[image-20240719215855633.png]]
为什么要用GT,而不用FString、FName,或者在某些情况下使用枚举或布尔值呢:
- GT 标签具有许多固有的特性,特别是层级属性,可以让我们的代码变得更加灵活有用的一种工具
- 两个标签可以进行精确相等或部分相等的比较,也许它们只共享相同的根标签名称,但这种情况在某些时候可能会很重要
![[image-20240719222048349.png]]
- GAS被设计成可以为几乎每个类中都使用游戏玩法标签
- GAS组件当然也可以有GT,并且能力玩法系统组件实现了一个成为IGameplayTagAssetInterface的接口
- IGameplayTagAssetInterface这个接口有许多函数,比如可以查看所有拥有的标签、检查是否拥有特定的标签或获取与给定标签匹配的所有标签等,这些都是接口函数,任何类都可以实现这个接口
![[image-20240719224457154.png]]
由于类可以有多个GT,不使用TArray,我们用游戏玩法标签容器(GameplayTagContainer)来存储它
![[image-20240719224934721.png]]
那这个GT 我们到底该怎么玩呢
- 现在GE可以有一个特定的标签,当他应用到ASC时,ASC就会有这个标签,当这个GE的duration结束,ASC也会移除那个特定的标签,我们就可以对此反应进行一些操作
- 再比如一个ASC可以有某些游戏能力(Gameplay Ability),目前还没讲到能力,就把它当成跳跃、重击的东西
- 但是这个ASC身上有一个Blocked的Tag,也就是说一旦这个ASC有这个标签,那我们就不能跳跃或者使出重击,无法激活这个Ability
- 又或者它必须有这个标签才能激活这个Ability等等
![[image-20240719233719196.png]]
- 当然标签还不止这些用途,还可以可以使用它们来识别:
- 输入、
- 能力Abilities、
- 属性Attributes、
- 伤害类型DDamage Types、
- 增益和减益Buffs/Debuffs
- 消息Messages
- Data任何类型的数据或者我们能想到的其它任何东西
① 创建GT
直接创建GT
进入项目设置 GameplayTags
![[image-20240720003016126.png]]
配置文件的位置,你也可以在这里手动输入
![[image-20240720003226818.png]]
![[image-20240720003346812.png]]
通过数据表创建GT
创建数据表蓝图
![[image-20240720010722898.png]]
选择行头类型,我们当前只对GT感兴趣,因此选GT 表头
![[image-20240720010802841.png]]
添加Tag
![[image-20240720020253581.png]]
导入数据表
![[image-20240720020341886.png]]
② GE中的标签组件介绍
GE中的GT分类有很多,点击Components.添加Array Item就能看到,这些标签都有不同的作用 ,它们都是被标签容器包装起来的,这里只找两常用的说说,之后再看其它的都可以见名之意
![[image-20240720152546559.png]]
Assert Tags 资产标签
Assert Tags 只是当前GE拥有但不会赋予给Actor的标签,也就是说将Tag添加到Assert Tags中,它并不会将该标签应用至受到此效果影响的角色身上
一般用途是可以在代码里通过获取资产tag来判断当前应用的GE有没有我们期望的标签 ,然后进行一系列操作
这里有三个不同的操作选项Combinde Tags、Added、Removed
假设当前的GE蓝图类是从某个GE蓝图父类的子类:
- Added : 当前你想添加的标签,直接添加就是了
- Removed : 如果我们想让这个子类不拥有某些继承的标签,我们就将其添加到移除部分
- Combined Tags = 从父类继承下来的标签 加上当前Added的标签 减去 Removed当中要删除的tag
![[image-20240720153854418.png]]
Target Tags 直接给目标授予标签
直接授予给Actor的标签,这里我们随便添加一个标签
![[image-20240720155315172.png]]
可以看到当我们捡起水晶的时候,会短暂的给我们角色一个Tag,直至这个GE的影响消失
![[recording 2.gif]]
Tag的层数
你可能注意到当获得标签的时候括号里有一个数字,没错,游戏标签也是可以叠层数的,但是注意:
- 如果你设置了Stack的层数(除了None以外的类型),不管你同时叠几层都算作一次的游戏效果,所以只能获得一个Tag
- 如果Stack设置为None,就相当于多次应用这个效果,每次都算作一个新的游戏效果,所以Tag会叠加
![[image-20240720160157389.png]]
当效果结束时,Tag层数依次减少
![[recording 3.gif]]
直接授予目标Tag的注意事项
- 只有当GE的duration不是瞬时效果的时候,授予Tag才有意义
- 因为对于瞬时效果来说,我们根本就没有获得过标签,所以当你给没有持续效果的GE配置 Target Tag的时候,会没有效果(获得tag的这个效果)
- 但是我就想知道当我捡起某个东西,根据某个标签来知道我们刚刚拾取了什么,并进行一些操作该咋整呢
- 这时候就需要用到上面提到的资产标签tag了,能力系统组件(ASC)提供了一些方法来知道任何类型的效果在什么时候被应用,ASC的头文件中有很多相应的委托,看看委托传递过来的GE中包含什么tag
- 比如 当应用GE、移除GE时、应用GE到self或者target时、我们绑定这个委托再从中检索我们需要的tag信息做出处理
![[image-20240720163810016.png]]
③ 使用GE的Delegate获取Tag
绑定委托
我们使用 ASC 中的委托来看看 如何获得我们Tag,这里我们选用OnGameplayEffectAppliedDelegateToSelf
绑定委托可以在Beginplay进行绑定测试
我这里采用的是在初始化了AbilityInfo之后,进行绑定以便这个功能有联机效果?:
- 在自己的AbilitySystemComponent类中创建委托的回调函数 和 InitSetting函数
- InitSetting函数由外部调用 ,在调用ASCInitAbilityActorInfo(对于玩家来说调用这个函数的地方在角色类,这里提到过:[[#4.初始化ACS的actor info]])之后手动调用
![[image-20240720181719092.png]]
![[image-20240720181812165.png]]
获取Tag
在我们的回调函数中获取GESpec,然后利用它获取资产标签,当前 其它的标签也是可以获取的,它有对应的函数
![[image-20240720184847071.png]]
![[image-20240720184948586.png]]
![[recording 4.gif]]
④ 在Cpp中获取Tag
- 之前可以通过FGameplayTag::RequestGameplayTag(FName(“XXX”))来获取Tag,但是在程序中到处写这种FName硬编码很难看
- 因此我们可以通过另外一种方法:
- 创建一个单例结构(类和结构体都可以)游戏标签类,我们在这里通过系统的游戏标签管理器创建所有的需要的游戏标签, 在cpp中添加的Tag称为Native Tag,创建标签时,戏标签管理器会返回这个值,因此我们可以将它作为成员变量,这样一来,在cpp中查询标签的时候就会有语法提示方便使用
- 创建继承于资产管理器的cpp类,然后引擎里设置默认的资产管理器类为当前这个类,最后通过资产管理器的方法StartInitialLoading()来加载初始化这些Tag
- 还有一种方法是继承自[[#创建 AbilitySystemGlobals 类]]的类,在这个类中创建我们自己的本地标签,这里我自己创建单例模式
在Cpp中添加Native GameplayTag
![[image-20240728001216359.png]]
注意:InitGameplayTags函数暂未调用,我们在资产管理器中初始化这些标签
![[image-20240728001328329.png]]
加载Natvie GameplayTags
![[image-20240728001431601.png]]
调用静态函数InitGameplayTags,确保后面游戏使用标签的时候这些东西都存在
![[image-20240728001451670.png]]
设置默认资产管理器
![[image-20240728001722267.png]]
重启编译,可以看到标签出现了
![[image-20240728012823925.png]]