98. UE5 GAS RPG 实现技能眩晕效果

时间:2024-10-12 15:58:06

我们在技能伤害基类上面设置了对应的负面效果应用的配置项,用来实现技能的负面效果应用。
在这里插入图片描述
在之前实现火球术的负面效果时,我们我们在创建火球时,通过伤害基类上的创建技能配置用于后续应用。
在这里插入图片描述
在火球攻击到敌人时,通过函数库书写的通过配置项应用到目标,我们将所需的配置设置到GE实例上
在这里插入图片描述
然后在AS里应用伤害时,我们去判断当前伤害是否需要应用负面效果,来实现负面效果的应用,然后调用函数实现对GE的添加。
在这里插入图片描述
在实现负面效果时,GE会将对应的负面效果标签应用给目标ASC
在这里插入图片描述
我们可以以此为切入点,通过判断角色的ASC身上的是否包含某个负面标签,来切换动作。

实现负面效果属性

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

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

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

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

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

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

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

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

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

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

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

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();
	...
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系统用来表现眩晕状态

按照之前火焰的负面效果灼烧的做法,我们再声明一个系统,用于定义眩晕的表现效果
在这里插入图片描述
在初始化时,创建对应的组件
在这里插入图片描述
我们专门实现了一个负面组件,用于即插即用的组件,如果需要添加一个,直接在类上面创建即可,在类上面,我们会监听对应的标签变动,来实现对应的表现效果的显示和隐藏。
在这里插入图片描述
就这样,实现了对应的效果。

实现敌人持续受击效果

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

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

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

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

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

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

在角色基类里覆写一下

	virtual void SetIsBeingShocked_Implementation(bool bInShock) override;
	virtual bool IsBeingShocked_Implementation() const override;

实现函数

void ARPGCharacterBase::SetIsBeingShocked_Implementation(bool bInShock)
{
	IsBeingShocked = bInShock;
}

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

在AS里设置敌人受击时增加额外的判断,判断当前目标是否处于持续受击状态
在这里插入图片描述
编译打开UE,我们在敌人基础动画蓝图里,在动画更新回调里增加对持续受击变量的获取
在这里插入图片描述
增加一个持续受击的状态切换
在这里插入图片描述
我们通过获取变量设置它的切换
在这里插入图片描述
然后在子动画蓝图里去设置实际使用的动画,记得播放器要设置循环播放
在这里插入图片描述
接下来,我们在命中目标后,如果目标继承了战斗接口,我们将其持续受击状态设置为true
在这里插入图片描述
额外目标也需要设置
在这里插入图片描述
记得在技能结束时,我们将其持续受击状态设置为false
在这里插入图片描述
将额外目标状态取消
在这里插入图片描述

实现眩晕效果

我们将在闪电链技能结束时,给主要目标施加一个眩晕效果。
所以,在技能结束,取消受击后,我们应用一个配置给目标
在这里插入图片描述
然后接着测试,查看技能结束是否显示眩晕
在这里插入图片描述
接着升级一级技能,查看是否能够扩散
在这里插入图片描述