GAS - Gameplay Attributes
Attribute
属性,记录Actor数值信息,类型为FGameplayAttributeData(目前就是float),常见的属性有血量、蓝量、攻击力、移动速度等等。通常使用Gameplay Effect来作用于Attribute,对属性值进行修改。
Gameplay Attribute可以说是这个系统的数据核心了,我们使用GAS的目的就是改变Actor的数值属性和状态(状态通常就是个二进制数Yes or No,使用Gameplay Tag)。设计技能也是从Actor拥有的属性出发的。
Attribute Set
Define and Configure attribute(定义和配置属性)
如何给Actor添加属性呢?这里要使用AttributeSet类,顾名思义,属性集类。在这个类中定义的float(被UPROPERTY标记)就是Attribute。
RPGAttributeSet,h
上图中的Health,MaxHealth,Mana都是属性,当然还有一些函数和宏定义,它们的功能后面细说。
创建好自己的AttributeSet类之后,必须使用AbilitySystemComponent注册它。实现方式有两种:
1、将其设为拥有AbilitySystemComponent的Actor的SubObject。
RPGCharacterBase.h
在构造函数中:
RPGCharacterBase.cpp
2、将类传给Ability System Component的GetOrCreateAttributeSubobject函数。
相关的响应函数(不知道该如何称呼,暂且定这个叫法)
当属性值发生变化时,或是施放GameplayEffect时,我们希望做一些处理,此时就需要系统提供的响应函数来进行操作。如ActionRPG中,实现了两个函数:
插播:写override是个好习惯!!!
响应函数主要有:
- PreAttributeBaseChange
- PreAttributeChange
- PreGameplayEffectExecute
- PostGameplayEffectExecute
这里要提一下,Base value和(Current) value的区别。Base value是永久修改的,而value是暂存,这里应该涉及到网络相关,GAS是支持客户端回滚的。
各函数描述:
注意!!只能应用修改符和Setter来改变属性值(current value),应该也是为同步服务的
PreAttributeBaseChange:在base value修改前调用。因为是永久修改,不允许使用temporary modifiers(修改符也是一个类,通常修改属性是使用GameplayEffect,里面定义了基本的修改符,也可以自己拓展),不应该在游戏逻辑中使用。最多用来做数值的Clamp。
PreAttributeChange:同上,只是这里可以使用temporary modifiers。例子:
RPGAttributeSet.cpp
PreGameplayEffectExecute,PostGameplayEffectExecute:顾名思义,技能释放前、后会被调用。
RPGAttributeSet.cpp
官方描述
Replication(网络)
需要在UPROPERTY中添加ReplicatedUsing = OnRep_MyAttribute,同时要在GetLifetimeReplicatedProps函数中设置LiftTime,于是最后会变得像是这样。
ActionRPG中是这样的,LifeTime的设置不一样,如果上图中说的无误,则ActionRPG这样设置在联机时可能会出现Error。
RPGAttributeSet.cpp
相关宏(Macro)
在前面的响应函数实现中,我们发现要使用许多Get函数,来获得属性或是属性值。幸好,引擎为我们准备好了宏。
AttributeSet.h
数据驱动
你可以用数据表来初始化你的AttributeSet。
初始化属性
最后附上ActionRPG的AttributeSet供参考:
RPGAttributeSet.h