98. UE5 GAS RPG 实现闪电链技能负面效果

我们在技能伤害基类上面设置了对应的负面效果应用的配置项,用来实现技能的负面效果应用。

在之前实现火球术的负面效果时,我们我们在创建火球时,通过伤害基类上的创建技能配置用于后续应用。

在火球攻击到敌人时,通过函数库书写的通过配置项应用到目标,我们将所需的配置设置到GE实例上

然后在AS里应用伤害时,我们去判断当前伤害是否需要应用负面效果,来实现负面效果的应用,然后调用函数实现对GE的添加。

在实现负面效果时,GE会将对应的负面效果标签应用给目标ASC

我们可以以此为切入点,通过判断角色的ASC身上的是否包含某个负面标签,来切换动作。

实现负面效果属性

我们在角色基类上面增加一个属性,用于记录当前的角色是否处于眩晕状态

cpp 复制代码
	//当前角色是否处于眩晕状态
	UPROPERTY(Replicated, BlueprintReadOnly)
	bool bIsStunned = false;

接着,我们增加保护性的配置,首先是注册监听负面标签变动的函数,然后增加一个眩晕标签变动的回调。我们把设置角色移动速度的配置从敌人的类里搬到了基类,因为角色眩晕时是无法移动的,我们需要去修改角色的最大移动速度。

cpp 复制代码
	//注册用于监听负面标签变动的函数
	void DeBuffRegisterChanged();

	//眩晕标签变动后的回调
	virtual void StunTagChanged(const FGameplayTag CallbackTag, int32 NewCount);

	//当前角色的最大移动速度
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Combat")
	float BaseWalkSpeed = 600.f;

然后我们实现监听负面标签变动函数,通过ASC去监听它的标签变动,并绑定眩晕标签变动回调。

cpp 复制代码
void ARPGCharacter::DeBuffRegisterChanged()
{
	//监听眩晕标签变动
	AbilitySystemComponent->RegisterGameplayTagEvent(FRPGGameplayTags::Get().DeBuff_Stun, EGameplayTagEventType::NewOrRemoved).AddUObject(this, &ARPGCharacter::StunTagChanged);
}

在眩晕标签变动回调里,我们根据角色身上的对应标签的数量,来设置变量的true或者false

cpp 复制代码
void ARPGCharacter::StunTagChanged(const FGameplayTag CallbackTag, int32 NewCount)
{
	bIsStunned = NewCount > 0;
	GetCharacterMovement()->MaxWalkSpeed = bIsStunned ? 0.f : BaseWalkSpeed;
}

接下来,就是需要在玩家角色类和敌人类里,初始化ASC完成后,调用监听函数

cpp 复制代码
void ARPGHero::InitAbilityActorInfo()
{
	ARPGPlayerState* PlayerStateBase = GetPlayerState<ARPGPlayerState>();
	check(PlayerStateBase); //检测是否有效,无效会暂停游戏
	//从playerState获取ASC和AS
	AbilitySystemComponent = PlayerStateBase->GetAbilitySystemComponent();
	AttributeSet = PlayerStateBase->GetAttributeSet();
	//初始化ASC
	AbilitySystemComponent->InitAbilityActorInfo(PlayerStateBase, this);
	//触发Actor的技能信息设置回调
	Cast<URPGAbilitySystemComponent>(AbilitySystemComponent)->AbilityActorInfoSet();

	//注册监听负面标签变动
	DeBuffRegisterChanged();
	...
cpp 复制代码
void ARPGEnemy::InitAbilityActorInfo()
{
	AbilitySystemComponent->InitAbilityActorInfo(this, this);
	Cast<URPGAbilitySystemComponent>(AbilitySystemComponent)->AbilityActorInfoSet();

	//注册监听负面标签变动
	DeBuffRegisterChanged();
	...

到这里,眩晕的布尔值可以跟随标签进行变动了,我们可以在动画蓝图中,进行监听此值来修改动画。

在敌人的动画蓝图中,我们将角色实例保存

然后在动画更新时,来获取角色是否处于眩晕状态。

接着增加一个切换状态,切换条件就是我们新增的变量

状态里,我们增加一个Sequence Player,用于设置使用的播放动画。

接着,在敌人基础动画蓝图继承的子蓝图里,我们对资产进行覆盖

接着,我们修改玩家动画蓝图,也一样在动画更新时,去更新动画蓝图新增的变量,记录当前的眩晕状态

然后增加一个眩晕状态,直接将动画拖上来即可,然后增加一个状态别名,不需要每个状态去设置对于它的连线。

在状态别名里,我们可以设置哪些状态要在眩晕属性为true时,切换到此状态。

我们记得将Sequence Player的循环动画开启,角色在眩晕时,可以循环播放。

对于敌人角色,我们还需要修改它们的AI控制器,在角色眩晕状态时,将停止移动和攻击玩家,我们在黑板里增加一个布尔变量,用于记录当前角色是否处于眩晕状态

在进行攻击执行的上面,我们增加一个黑板装饰器,用于判断此变量

设置一下顺序

然后将键查询设置为未设置,如果眩晕属性为true,将执行观察器终止操作。

如果要测试在闪电链中当前函数是否也能够执行,我们可以在蓝图中,比如技能结束时,给命中目标应用一个创建的负面效果

我们可以在场景中只保留一个怪,然后运行时打开AI控制器,来查看属性变化。以及角色的动画状态。

实现角色眩晕状态终止操作

我们之前实现过,通过设置标签来阻止玩家的输入,教程里是通过在应用负面Buff时,给ASC增加对应的标签,我这里考虑不方便修改,所以,准备另辟蹊径,通过使用一个自动触发的技能来实现。

我们基于自定义的技能基类创建一个技能类,这样,在设置给角色是,它能够顺利的添加的角色身上。

我们这里新增加了一个技能标签,然后在Cancel Abilities with Tag里设置了所有主动技能的标签,在技能激活时,含有这些标签的技能都将被结束激活。

接着,我们将玩家操作对应的标签设置给ASC,玩家在眩晕状态进行这些操作时,将无法触发。

接着,就是重点,我们在触发器这里,增加一个索引,来监听负面标签是否存在,如果存在,此技能将自动激活,Trigger Source设置为Owned Tag Present,如果角色身上存在此标签,技能将处于激活状态,在失去此标签时,技能也将被终止。

增加Niagara系统用来表现眩晕状态

按照之前火焰的负面效果灼烧的做法,我们再声明一个系统,用于定义眩晕的表现效果

在初始化时,创建对应的组件

我们专门实现了一个负面组件,用于即插即用的组件,如果需要添加一个,直接在类上面创建即可,在类上面,我们会监听对应的标签变动,来实现对应的表现效果的显示和隐藏。

就这样,实现了对应的效果。

实现敌人持续受击效果

在敌人受到闪电链的攻击时,它将会受到一秒十次的攻击,所以受击也会一秒触发十次,效果不是很好,所以,我们将实现一个持续受击状态,在持续受击时,敌人将不在触发受击,而是持续播放循环受击效果。

我们在角色基础类里增加一个变量,设置为可复制,在多端都可以展示对应的效果。

cpp 复制代码
	//当前角色是否处于持续攻击状态
	UPROPERTY(Replicated, BlueprintReadOnly)
	bool IsBeingShocked = false;

在战斗接口里,增加两个函数,用于设置和获取参数

cpp 复制代码
	/**
	 * 获取角色是否处于闪电链攻击状态
	 * @return 布尔值,如果处于返回true
	 */
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
	bool IsBeingShocked() const;

	/**
	 * 设置角色是否处于闪电链攻击状态
	 * @param bInShock 
	 */
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
	void SetIsBeingShocked(bool bInShock);

在角色基类里覆写一下

cpp 复制代码
	virtual void SetIsBeingShocked_Implementation(bool bInShock) override;
	virtual bool IsBeingShocked_Implementation() const override;

实现函数

cpp 复制代码
void ARPGCharacterBase::SetIsBeingShocked_Implementation(bool bInShock)
{
	IsBeingShocked = bInShock;
}

bool ARPGCharacterBase::IsBeingShocked_Implementation() const
{
	return IsBeingShocked;
}

在AS里设置敌人受击时增加额外的判断,判断当前目标是否处于持续受击状态

编译打开UE,我们在敌人基础动画蓝图里,在动画更新回调里增加对持续受击变量的获取

增加一个持续受击的状态切换

我们通过获取变量设置它的切换

然后在子动画蓝图里去设置实际使用的动画,记得播放器要设置循环播放

接下来,我们在命中目标后,如果目标继承了战斗接口,我们将其持续受击状态设置为true

额外目标也需要设置

记得在技能结束时,我们将其持续受击状态设置为false

将额外目标状态取消

实现眩晕效果

我们将在闪电链技能结束时,给主要目标施加一个眩晕效果。

所以,在技能结束,取消受击后,我们应用一个配置给目标

然后接着测试,查看技能结束是否显示眩晕

接着升级一级技能,查看是否能够扩散

相关推荐
测试工坊3 小时前
Android 视频播放卡顿检测——帧率之外的第二战场
android
Kapaseker5 小时前
一杯美式深入理解 data class
android·kotlin
鹏多多5 小时前
Flutter使用screenshot进行截屏和截长图以及分享保存的全流程指南
android·前端·flutter
Carson带你学Android5 小时前
OpenClaw移动端要来了?Android官宣AI原生支持App Functions
android
黄林晴5 小时前
Android 删了 XML 预览,现在你必须学 Compose 了
android
三少爷的鞋6 小时前
Android 面试系列 | 内存泄露:从"手动配对"到"架构自愈"
android
恋猫de小郭6 小时前
什么 AI 写 Android 最好用?官方做了一个基准测试排名
android·前端·flutter
louisgeek15 小时前
Android MediatorLiveData
android
锋风1 天前
远程服务器运行Android Studio开发aosp源码
android
测试工坊1 天前
Android UI 卡顿量化——用数据回答"到底有多卡"
android