10. UE5 RPG使用GameEffect创建血瓶修改角色属性

前面我们通过代码实现了UI显示角色的血量和蓝量,并实现了初始化和在数值变动时实时更新。为了测试方便,没有使用GameEffect去修改角色的属性,而是通过代码直接修改的数值。

对于GameEffect的基础,这里不再讲解,如果需要可以查看文档。
虚幻引擎游戏技能系统文档

接下来,讲解一下,如何使用GameEffect进行属性修改。

实现拾取物的Effect

之前,我们创建了一个Actor的类,用于修改,现在将其内容还原成一个刚创建的模样。

为了保证类的通用性,我们删除了所有的内容,只添加了一个根节点。如果你需要一些内容,可以在蓝图内添加。

bash 复制代码
SetRootComponent(CreateDefaultSubobject<USceneComponent>("SceneRoot"));

打开UE,在根节点下面添加一个静态网格体,用于添加显示模型。

接着将静态网格体的碰撞关闭掉,因为我们不需要它进行碰撞检测

在根组件下面再添加一个球碰撞体,用于碰撞检测

球碰撞体是默认对所有物体进行检测的

添加球体的碰撞检测事件通知

添加到这里,就可以先将UE关闭,我们可以将一些使用蓝图方便编辑的内容在蓝图中制作,一些比较耗性能的内容或运算比较高的内容放到c++内做。

实现赋予类给自身添加GameplayEffect

上面通过蓝图添加了碰撞检测,我们将在碰撞检测之后链接在c++里创建的函数,为角色身份赋予effect效果。

打开代码编辑器,在拾取物基类里添加一个函数,通过类赋予目标Effect的函数,设置这个函数可以在蓝图可调用。

bash 复制代码
	UFUNCTION(BlueprintCallable) 
	void ApplyEffectToTarget(AActor* TargetActor, TSubclassOf<UGameplayEffect> GameplayEffectClass);//给与目标添加GameplayEffect

函数实现里,首先要获取到添加目标的ASC组件,这里我们使用到了技能组件库里面的函数获取,

bash 复制代码
UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(TargetActor);

使用ASC创建一个EffectContextHandle,这个句柄里面包含实例化GameplayEffect所需的数据

bash 复制代码
FGameplayEffectContextHandle EffectContextHandle = TargetASC->MakeEffectContext();

设置此句柄的创建者

bash 复制代码
EffectContextHandle.AddSourceObject(this);

通过MakeOutgoingSpec()函数实例化GameplayEffect,返回一个实例化的句柄(句柄的意思是可以跟踪实例化对象的位置,即使它位置变动了也能跟踪的到)

MakeOutgoingSpec()函数需要传入三个值,第一个就是需要实例化的类,第二个是效果等级(它是有等级区分的),第三个值就是我们之前创建的实例化所需数据的句柄。

bash 复制代码
const FGameplayEffectSpecHandle EffectSpecHandle = TargetASC->MakeOutgoingSpec(GameplayEffectClass, 1.f, EffectContextHandle);

最后,我们需要从实例化对象中拿到它的实际位置,并调用ASC赋予自身。

bash 复制代码
TargetASC->ApplyGameplayEffectSpecToSelf(*EffectSpecHandle.Data.Get());

打开拾取物蓝图,搜索对应的名称,如果出现当前函数节点,证明我们成功了

我们也可以直接用蓝图制作,下面是蓝图实现方式

创建GameplayEffect

接下来我们创建GameplayEffect,这个不需要在c++里编写,直接创建蓝图编辑即可。接下来,我们将创建一个药瓶的效果,能够瞬间恢复一定血量的效果。

创建一个基于GameplayEffect的蓝图类

在右侧的细节设置相关的配置项,其实这个蓝图就是一个数据蓝图,新版本5.3的配置还改版了,之前是一堆直接罗列出来,现在新增加了一个Components配置,可以自己按照需求添加,这个感觉改版改的挺好。

在持续时间这里,有三个选项Instant瞬间(也可以理解为永久),Infinite(无限时间,可以后续被去掉,比如永久buff),Has Duration(具有时效性),血瓶作为直接恢复血量的,不会再被去掉恢复的血量,可以使用Instant

在下面的Modifiers这里,添加一个数组元素

它的Attribute设置需要选择我们需要修改的选项,血瓶需要修改血量,选择在属性集里创建的Health属性

计算方式有加,乘,除,覆盖数值,无效,有小伙伴会问,为什么没有减,加的数值是负数就是减了。

这里血量恢复就是加,所以我们使用add,一瓶血恢复十点生命值

到这里,我们的血量恢复的Effect就编写完成了。

添加蓝图逻辑

首先在c++类里添加一个参数,用于设置类,这个类可以被蓝图设置,并被蓝图读取。

bash 复制代码
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Apply Effects")
	TSubclassOf<UGameplayEffect> InstantGameplayEffectClass; //生成GameplayEffect的类

打开对应蓝图后,在类默认值的细节这里,我们可以设置对应的Effect类,直接选择我们创建的Effect

然后再碰撞事件后,将角色转换成角色,直接应用对应的设置的Effect类,最后销毁Actor

接着将actor添加到场景中,运行游戏,调试框输入showdebug abilitysystem

左侧显示血量数值当前为50

操作角色去吃掉血瓶,会发现血量增加10

制作有时间限制的GameplayEffect

前面实现了即时的效果,接下来实现一个只可以维持一段时间的效果的药瓶。

我们将制作一个增加最大血量值的GameplayEffect,持续时间为5s,过了这个时间以后,效果将恢复为原来的最大血量。

首先将持续时间修改成Has Duration(具有时效性的),设置时间为5s,Period设置为0,意为整个周期内都起作用。

然后在属性这里修改一个MaxHealth,修改数值增加100

为了防止混淆,这里直接增加了一个设置DurationGameplayEffectClass参数

bash 复制代码
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Apply Effects")
	TSubclassOf<UGameplayEffect> DurationGameplayEffectClass; //生成具有一定持续时间的GameplayEffect的类

逻辑也是直接使用蓝图实现的

运行,打开debug,默认值MaxHealth是100

去拾取新创建的碰撞体,会告诉你增加了100,基础还是100,5s后恢复默认的base。

实现持续回血效果的GameplayEffect

上面实现了可以维持一段时间的效果,可以作为某些属性使用,但是正常使用血瓶,它会在一定时间内持续回血,接下来我们将实现这个效果。

这个效果和上面的主要区别在于Period的值不能为0,就是不会一直触发,而是有间隔时间,我们设置每间隔一秒执行一次。

Execute Periodic Effect on Application 如果勾选,将会在触发时,立马触发一次效果,而不是等待Period的时间后再触发。

Periodic Inhibition Policy 选择 Never Reset 则属性每次添加不会重置,相当于每过1秒触发一次Instant

下面,我们修改成了修改血量的值,每次触发恢复10点血量

相关推荐
咖肥猫8 小时前
【ue5学习笔记2】在场景放入一个物体的蓝图输入事件无效?
笔记·学习·ue5
我的巨剑能轻松搅动潮汐3 天前
【UE5】pmx导入UE5,套动作。(防止“气球人”现象。
ue5
windwind20003 天前
UE5 跟踪能力的简单小怪
ue5
Deveuper5 天前
UE5 C+、C++、C# 构造方法区别示例
c++·ue5·c#·ue4
windwind20005 天前
UE5 学习方法的思考
ue5·学习方法
ue星空7 天前
UE材质常用节点
ue5·虚幻·材质·虚幻引擎
Zhichao_977 天前
【UE5 C++课程系列笔记】09——多播委托的基本使用
笔记·ue5
异次元的归来9 天前
UE5的TRS矩阵
线性代数·矩阵·ue5·游戏引擎·unreal engine
电子云与长程纠缠9 天前
UE5编辑器下将RenderTarget输出为UTexture并保存
学习·ue5·编辑器·虚幻
ue星空10 天前
虚幻5描边轮廓材质
ue5·材质