69. UE5 RPG 使用Gameplay Cue 实现技能表现效果

在上一章中,我们实现了敌人的攻击技能的特效和音效。如果我们在多人模式下打开,发现,其它客户端看不到对应的效果。

造成这种问题的原因是因为敌人的技能是运行在服务器端的,它只复制到拥有它的客户端,而敌人的效果对于客户端来说,它们都不拥有此内容,所以无法查看到。

那么如何实现每个客户端都可以查看到和听到所需的效果呢,这里就需要使用gameplay Cue去实现了。它可以实现让每个客户端都能获得同样的视效和音效。

创建GameplayCue

右键点击创建蓝图,搜索gameplaycue。

我们会发现对应的可以创建两种GameplayCue,一种是集成至Actor,它是被实例化的,并且可以做到每一帧更新状态和数据。另一种静态的,是无法被实例化,对于一次性的效果很有用。

我们这里选择GameplayCueNotify_Static作为基类,创建通过通知实现。

我们以简写GC为前缀,表示它是一个GameplayCue,这个作为受击的效果。

进入蓝图,选择重载On Execute,在技能被触发时,将触发此节点的回调。

我们打开传递过来的参数,发现有很多的配置项,这些都是我们在调用时可以设置的。

我们通过Source object获取到角色的受伤特效,生成一个粒子特效

触发Gameplay Cue

现在,我们创建了一个GC,还没有实现对其的触发,让其播放特效。如果要实现特效的播放,我们需要通过标签去触发。

打开项目设置,GameplayTag标签管理器,有一个GameplayCue,这个是专门用于设置GC使用的标签地方。

我们在下面添加一个受击特效标签

然后回到GC里面设置,你会发现,在这里只能选择GameplayCue下面的标签,我们选中标签

这样就实现了GC的制作,我们回到技能蓝图中,要能够触发GC,我们使用Execute GameplayCue Width Params On Owner节点,这个可以通过设置Tag来选择需要激活的标签,并且还能够传入配置项

然后,我们将节点拖出,制作一个配置项,并将所需的内容设置上去

在客户端查看效果即可。可以看到在客户端也能触发特效表现。

修改敌人技能蒙太奇标签

接下来,我们要实现敌人技能的音效在多个客户端上面触发,音效是设置在蒙太奇的结构体当中的,查看配置项,我们是无法直接将配置项传递的。

所以,我们需要修改结构体,增加一个技能独有的索引,并实现一个函数,通过标签去获取对应的结构体数据。

首先我们在C++里面将标签改掉

之前的Montage标签修改为战斗接口标签

cpp 复制代码
	FGameplayTag CombatSocket_Weapon; //使用武器攻击部位标签
	FGameplayTag CombatSocket_RightHand; //右手攻击部位标签
	FGameplayTag CombatSocket_LeftHand; //左手攻击部位标签

在cpp文件中将注册代码也修改掉

cpp 复制代码
	/*
	 * CombatSocket
	*/
	
	GameplayTags.CombatSocket_Weapon = UGameplayTagsManager::Get()
		.AddNativeGameplayTag(
			FName("CombatSocket.Weapon"),
			FString("使用武器攻击部位标签")
			);
	GameplayTags.CombatSocket_LeftHand = UGameplayTagsManager::Get()
		.AddNativeGameplayTag(
			FName("CombatSocket.LeftHand"),
			FString("左手攻击部位标签")
			);
	GameplayTags.CombatSocket_RightHand = UGameplayTagsManager::Get()
		.AddNativeGameplayTag(
			FName("CombatSocket.RightHand"),
			FString("右手攻击部位标签")
		);

然后我们增加对于动作设置新的索引,在标签中新增,这里我们新增四个

cpp 复制代码
	//使用攻击动作索引
	FGameplayTag Montage_Attack_1; 
	FGameplayTag Montage_Attack_2;
	FGameplayTag Montage_Attack_3;
	FGameplayTag Montage_Attack_4;

对UE中进行注册

/*

* Montage Attack Index

*/

GameplayTags.Montage_Attack_1 = UGameplayTagsManager::Get()
	.AddNativeGameplayTag(
		FName("Montage.Attack.1"),
		FString("第1个蒙太奇攻击标签")
		);

GameplayTags.Montage_Attack_2 = UGameplayTagsManager::Get()
	.AddNativeGameplayTag(
		FName("Montage.Attack.2"),
		FString("第2个蒙太奇攻击标签")
		);

GameplayTags.Montage_Attack_3 = UGameplayTagsManager::Get()
	.AddNativeGameplayTag(
		FName("Montage.Attack.3"),
		FString("第3个蒙太奇攻击标签")
		);

GameplayTags.Montage_Attack_4 = UGameplayTagsManager::Get()
	.AddNativeGameplayTag(
		FName("Montage.Attack.4"),
		FString("第4个蒙太奇攻击标签")
		);

接下来,我们在结构体中,增加一个部位的设置,原来的用来设置索引

cpp 复制代码
//蒙太奇动画和标签以及骨骼位置的映射,用于攻击技能获取和设置攻击范围
USTRUCT(BlueprintType)
struct FTaggedMontage
{
	GENERATED_BODY()

	//使用的蒙太奇
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	UAnimMontage* Montage = nullptr;

	//当前数据的索引
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTag MontageTag;

	//部位对应的标签
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTag SocketTag;

	//攻击时的触发伤害的骨骼插槽
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FName CombatTipSocketName; //设置技能释放的位置
	
	//攻击时的触发音效
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	USoundBase* ImpactSound = nullptr;
};

接着将代码中使用到的地方修改掉

然后编译,修改UE蓝图中使用的内容

在技能蓝图中,修改使用接收信息的标签

去蓝图中,修改每个角色的攻击蒙太奇的数据,

然后点击进入对应的蒙太奇,修改对应的位置标签

我们将这四个怪物都修改掉,技能有近战攻击和远程攻击两个需求把标签修改掉。修改完成运行查看效果是否有问题,主要查看技能是否都能够正确触发,技能释放的位置是否正确。

实现播放音效的GameplayCue

在上面,我们修改完成了标签重构工作。最后,我们还需要实现一个通过标签从结构体数组中获取对应的结构体。

在战斗接口中增加一个函数

cpp 复制代码
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
	FTaggedMontage GetTaggedMontageByTag(const FGameplayTag& MontageTag); //通过标签获取对应的结构体

然后在角色基类里面覆写它

cpp 复制代码
virtual FTaggedMontage GetTaggedMontageByTag_Implementation(const FGameplayTag& MontageTag) override;

在cpp里面实现函数,我们只需要遍历数组,判断MontageTag即可

cpp 复制代码
FTaggedMontage ARPGCharacter::GetTaggedMontageByTag_Implementation(const FGameplayTag& MontageTag)
{
	for(FTaggedMontage TaggedMontage : AttackMontage)
	{
		if(TaggedMontage.MontageTag.MatchesTagExact(MontageTag))
		{
			return TaggedMontage;
		}
	}
	return FTaggedMontage();
}

编译打开UE,我们接着创建一个新的GC,用来播放攻击音效

这里,我们需要传入一个TagContainer(标签集合)一个位置,以及释放技能的角色,通过标签集合获取到使用的MontageTag,然后去获取结构体,然后通过结构体内的音效配置项和位置进行播放音效。

标签这里,我也创建了一个新的标签

接下来,就是将此部分替换掉

我们将其替换成通过标签触发GC

如果你不确定有没有问题,可以在GC里面打印音效名称

查看是否能够成功打印对应的名称

相关推荐
运维-大白同学4 分钟前
将django+vue项目发布部署到服务器
服务器·vue.js·django
Winston Wood16 分钟前
Perfetto学习大全
android·性能优化·perfetto
烦躁的大鼻嘎20 分钟前
【Linux】深入理解GCC/G++编译流程及库文件管理
linux·运维·服务器
乐大师20 分钟前
Deepin登录后提示“解锁登陆密钥环里的密码不匹配”
运维·服务器
ac.char27 分钟前
在 Ubuntu 上安装 Yarn 环境
linux·运维·服务器·ubuntu
敲上瘾27 分钟前
操作系统的理解
linux·运维·服务器·c++·大模型·操作系统·aigc
EterNity_TiMe_44 分钟前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
soulteary2 小时前
突破内存限制:Mac Mini M2 服务器化实践指南
运维·服务器·redis·macos·arm·pika
程序猿进阶2 小时前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
爱吃青椒不爱吃西红柿‍️2 小时前
华为ASP与CSP是什么?
服务器·前端·数据库