46. UE5 RPG 增加角色受击反馈

在前面的文章中,我们实现了对敌人的属性的初始化,现在敌人也拥有的自己的属性值,技能击中敌人后,也能够实现血量的减少。
现在还需要的就是在技能击中敌人后,需要敌人进行一些击中反馈,比如敌人被技能击中后,可以播放击中的动画,并且显示伤害值。
我们在这一篇文章中,实现敌人被英雄的技能击中时,会播放受击动画,并且在敌人身上添加一个受击标签,角色在受击时,根据标签判断设置移动速度

设置角色受击标签

首先,我们实现在敌人身上添加标签,我们需要通过GE去添加。
创建一个新的GE
在这里插入图片描述
命名为GE_HitReact
在这里插入图片描述
在里面设置持续时间设置无限时间,我们在技能里面应用它,然后在技能结束是,将其清除
在这里插入图片描述
现在,我们还没有受击对应的标签,在c++里添加一个

FGameplayTag Effects_HitReact; //受击 标签
GameplayTags.Effects_HitReact = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Effects.HitReact"),FString("受到攻击时,赋予的标签"));

然后在GE里面使用TargetTagsGameplayEffectComponent组件,它可以将标签应用到目标角色身上
在这里插入图片描述

角色监听标签并设置移动速度

我们接下来实现对受击标签的监听,在源码中,受击标签会返回监听的标签和添加标签的个数
在这里插入图片描述
在这里插入图片描述
我们创建一个委托回调函数

void HitReactTagChanged(const FGameplayTag CallbackTag, int32 NewCount);

并创建变量来表示角色是否处于受击状态

UPROPERTY(BlueprintReadOnly, Category="Combat")
bool bHitReacting = false; //当前是否处于被攻击状态UPROPERTY(BlueprintReadOnly, Category="Combat")
float BaseWalkSpeed = 250.f; //当前角色的最大移动速度

在AEnemyBase::BeginPlay()中,我们设置对监听函数的回调

AbilitySystemComponent->RegisterGameplayTagEvent(FMyGameplayTags::Get().Effects_HitReact, EGameplayTagEventType::NewOrRemoved).AddUObject(this, &ThisClass::HitReactTagChanged);

如果数量大于0,则将其的移动速度设置为0

void AEnemyBase::HitReactTagChanged(const FGameplayTag CallbackTag, int32 NewCount)
{bHitReacting = NewCount > 0;GetCharacterMovement()->MaxWalkSpeed = bHitReacting ? 0.f : BaseWalkSpeed;
}

创建一个受击技能,并应用GE

接下来,我们创建一个新的技能,用来实现受击,是的,受击也是角色的技能。在角色受到攻击时,将触发角色受击技能来实现受击效果。
在这里插入图片描述
在技能触发时,我们将受击标签添加到角色身上,这样,之前监听角色标签的回调函数将触发,并设置移动速度,我们并将句柄保持,在技能结束时,方便移除GE
在这里插入图片描述

实现设置角色的受击蒙太奇动画

接下来,我们将实现角色受击时播放蒙太奇动画,为了保证通用性,我们将其设置为一个函数,并设置到战斗接口中,这样只需要在战斗接口中获取对应角色的蒙太奇即可。(每个角色的受击动画不一定一样)
首先在战斗接口中实现一个函数,这函数可以在蓝图中被覆写,也可以在蓝图中调用。

UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
UAnimMontage* GetHitReactMontage(); //获取受击蒙太奇动画

然后,我们在角色的基类里,对这个函数进行覆写。

virtual UAnimMontage* GetHitReactMontage_Implementation() override;

并增加一个参数用于设置蒙太奇

UPROPERTY(EditAnywhere, Category="Combat")
TObjectPtr<UAnimMontage> HitReactMontage;

在函数实现这里,直接返回蒙太奇

UAnimMontage* ACharacterBase::GetHitReactMontage_Implementation()
{return HitReactMontage;
}

接着在技能里面,将ASC控制的角色转换为战斗接口,从战斗接口调用函数获取到角色设置的蒙太奇进行播放
在这里插入图片描述
接下来就是基于动画创建蒙太奇
在这里插入图片描述
并将蒙太奇设置到角色身上,用于函数返回。
在这里插入图片描述

激活受击技能

接下来,就是我们实现对技能的激活,和上一篇一样,我们创建了一个敌人的DataAsset,我们希望可以将敌人所拥有的初始技能都设置在数据里,并在初始化时使用。
在CharacterClassInfo.h里增加一个参数,用于设置创建敌人时所拥有的初始技能

	UPROPERTY(EditDefaultsOnly, Category="Common Class Defaults")TArray<TSubclassOf<UGameplayAbility>> CommonAbilities;

之前英雄角色初始化技能我们创建了一个应用技能的函数
在这里插入图片描述
它是创建技能实例,并给与ASC,我们将给敌人创建一个通用的函数,并放到函数库中
在这里插入图片描述
在函数技能库里新增一个函数用于初始化角色技能

//初始化角色的技能
UFUNCTION(BlueprintCallable, Category="MyAbilitySystemLibrary|CharacterClassDefaults")
static void GiveStartupAbilities(const UObject* WorldContextObject, UAbilitySystemComponent* ASC);

函数实现就是获取到数据资产里面的技能列表,创建实例并给与角色

void UMyAbilitySystemBlueprintLibrary::GiveStartupAbilities(const UObject* WorldContextObject, UAbilitySystemComponent* ASC)
{//获取到当前关卡的GameMode实例const AMyGameModeBase* GameMode = Cast<AMyGameModeBase>(UGameplayStatics::GetGameMode(WorldContextObject));if(GameMode == nullptr) return;const AActor* AvatarActor = ASC->GetAvatarActor();//从实例获取到关卡角色的配置UCharacterClassInfo* CharacterClassInfo = GameMode->CharacterClassInfo;//遍历角色拥有的技能数组for(const TSubclassOf<UGameplayAbility> AbilityClass : CharacterClassInfo->CommonAbilities){FGameplayAbilitySpec AbilitySpec = FGameplayAbilitySpec(AbilityClass, 1); //创建技能实例ASC->GiveAbility(AbilitySpec); //只应用不激活}
}

在敌人基类里,开始事件时,我们调用函数库的初始化技能函数,将技能应用到角色身上

void AEnemyBase::BeginPlay()
{Super::BeginPlay();//设置角色的初始移动速度GetCharacterMovement()->MaxWalkSpeed = BaseWalkSpeed;//初始化角色的ASCInitAbilityActorInfo();//初始化角色的技能UMyAbilitySystemBlueprintLibrary::GiveStartupAbilities(this, AbilitySystemComponent);...

方便测试,在PostGameplayEffectExecute函数里,之前设置血量下面有判断,我们在角色没有被击杀时,让其触发受击技能。激活我们是使用的根据标签激活,它需要传入一个FGameplayTagContainer 类型的参数。

	if(Data.EvaluatedData.Attribute == GetIncomingDamageAttribute()){const float LocalIncomingDamage = GetIncomingDamage();SetIncomingDamage(0.f);if(LocalIncomingDamage > 0.f){const float NewHealth = GetHealth() - LocalIncomingDamage;SetHealth(FMath::Clamp(NewHealth, 0.f, GetMaxHealth()));const bool bFatal = NewHealth <= 0.f; //血量小于等于0时,角色将会死亡if(!bFatal){FGameplayTagContainer TagContainer;TagContainer.AddTag(FMyGameplayTags::Get().Effects_HitReact);Props.TargetASC->TryActivateAbilitiesByTag(TagContainer); //根据tag标签激活技能}}}

接下来,编译代码,打开UE,将我们之前创建的受击技能设置到数据资产中
在这里插入图片描述
我们将使用标签激活技能,所以,在技能里,还需要将受击标签设置给技能
在这里插入图片描述
我们不需要在每次激活时创建一个新的实例,只需要一个角色生成一个实例重复利用即可。
在这里插入图片描述
由于它一个角色对应一个单例,每次触发都是相同的实例,所以,我们需要在其播放完成后,将其结束,才可以触发,所以,在敌人的受击动画播放完成后,我们需要将敌人身上的受击标签清楚(如果GE添加的,只需要将对应的GE清除,标签也会随着清除)并结束技能。
在这里插入图片描述
接下来,就是测试效果,我们攻击敌人,看看其是否能够播放动画。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/8939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-10.1-NXP SDK 移植

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

夸克网盘拉新怎么做?分享网盘拉新攻略!

夸克网盘拉新怎么做&#xff1f;如何通过推广夸克网盘来赚佣金&#xff1f;相信大家应该都使用过夸克网盘&#xff0c;现在夸克网盘的拉新赚佣金活动开展的如火如荼&#xff0c;不少朋友通过夸克网盘拉新赚取收益&#xff0c;真的很香。还有一部分想要赚佣金但是不知道如何操作…

C语言例题39、输入一个正整数,将其反方向逆序输出

#include <stdio.h>void main() {int x;int ge; //个位int result 0;printf("请输入一个正整数&#xff1a;");scanf("%d", &x);while (x > 0) {//解题原理ge x % 10;//每次分解取得个位的数字result result * 10 ge;//个十百千万顺序向左…

libcity 笔记:添加自定义dataset

假设我们把libcity/data/dataset/trajectory_dataset.py复制一份到libcity/data/dataset/dataset_subclass/GeolifeDM_dataset.py&#xff0c;里面内容不变&#xff0c;只是把class的名字换了 那其他需要修改哪些内容&#xff0c;使得这个dataset生效呢 libcity/data/dataset/d…

Python应用:让生活更智能

随着科技的进步&#xff0c;Python已成为一种非常受欢迎的编程语言&#xff0c;它在数据分析、人工智能、Web开发等领域有着广泛的应用。今天&#xff0c;我们将探讨一个Python应用的例子&#xff0c;这个应用将帮助我们更智能地管理日常生活。 应用名称&#xff1a;智能生活助…

福建 | 福建铭发用行动诠释“敢为天下先”的泉州精神

福建铭发 泉州TOP级企业 在福建&#xff0c;提到混凝土搅拌站&#xff0c;铭发是绕不开的一个存在。 他们是当地最早一批建成的商砼企业&#xff0c;也是如今发展规模最大的TOP级企业。 从2007年建站至今&#xff0c;近15年的发展&#xff0c;他们形成了一套铭发特色的企业经…

Windows平台PyCharm之PySide6开发环境搭建与配置

PySide6 是一个用于创建跨平台 GUI 应用程序的库&#xff0c;它是 Qt for Python 的官方库。Qt 是一个跨平台的 C 应用程序框架&#xff0c;用于开发具有图形用户界面&#xff08;GUI&#xff09;的应用程序。PySide6 允许开发者使用 Python 语言访问 Qt 的功能&#xff0c;从而…

数据结构(十一)----图的应用

目录 一.最小生成树 1.Prim算法&#xff08;普里姆&#xff09; 2.Kruskal算法(克鲁斯卡尔): 二.最短路径&#xff08;BFS算法&#xff09; 1.单源最短路径 &#xff08;1&#xff09;BFS算法&#xff08;无权图&#xff09; &#xff08;2&#xff09;Dijkstra算法&…

不走寻常路!酷开科技不断升级酷开系统满足消费者日益增长的需求

在科技日新月异的今天&#xff0c;人们对生活品质的要求越来越高。为此&#xff0c;酷开科技不断升级酷开系统&#xff0c;以满足消费者日益增长的需求。为了让消费者体验更好的服务&#xff0c;在酷开系统中设立了酷开会员&#xff0c;满足消费者的更多需求。丰富的特权和定制…

STL学习笔记

1 基本概念 1.1 STL STL(Standard Template Library,标准模板库)STL从广义上分为: 容器(container) 算法(algorithm) 选代器(iterator)容器和算法之间通过迭代器&#xff08;看作指针&#xff09;进行无缝连接STL 几乎所有的代码都采用了横板类或者模板函数 1.2 容器 STL容器…

图片如何压缩到500kb以下?3步完成图片压缩

在日常生活和工作中&#xff0c;经常需要处理各种图片&#xff0c;而有时候图片文件过大&#xff0c;不仅占用了大量的存储空间&#xff0c;还可能影响文件的传输速度和加载速度。因此&#xff0c;如何将图片压缩到500kb以内成为了许多人的需求&#xff0c;普通的图片压缩可能没…

使用Docker安装Whistle Web Debugging Proxy

大家好&#xff0c;继续给大家分享如何使用docker来安装Whistle Web Debugging Proxy&#xff0c;关于Whistle Web Debugging Proxy的介绍和使用&#xff0c;大家可以参考下面文章&#xff0c;希望本文能够给大家的工作带来一定帮助。 Whistle Web Debugging Proxy介绍及使用 …

vue+lodop实现web端打印标签功能

背景&#xff1a;项目要求在web端连接标签打印机&#xff0c;打印收件人信息 lodop打印插件地址&#xff1a;Lodop和C-Lodop官网主站 在项目中使用 1、去官网下载lodop包下载中心 - Lodop和C-Lodop官网主站 windows系统直接下载windows32版的就可以 2、解压安装 点击CLodop…

SpringCloud Config 分布式配置中心

SpringCloud Config 分布式配置中心 概述分布式系统面临的——配置问题ConfigServer的作用 Config服务端配置Config客户端配置 可以有一个非常轻量级的集中式管理来协调这些服务 概述 分布式系统面临的——配置问题 微服务意味着要将单体应用中的业务拆分成一个个字服务&…

python如何整体缩进

python自带编辑器的缩进和取消缩进快捷键&#xff1a; 整体缩进 Ctrl【 整体取消缩进 Ctrl】 pycharm编辑器的缩进和取消缩进快捷键&#xff1a; 整体缩进&#xff1a; tab 整体取消缩进&#xff1a; tabshift

HDMI ARC功能详解及应用介绍

一、HDMI HDMI(High-Definition Multimedia Interface&#xff0c;高清多媒体接口)&#xff0c;是一种专用的音频/视频接口&#xff0c;用于发送未压缩的视频数据和压缩/未压缩的音频数据。HDMI是模拟视频标准的数字替代品。HDMI视频和音频信号传输通道采用了TMDS&#xff08;T…

【经验总结】Vue2中的全局变量(store

需求场景 需要在vue中存储一个可变的&#xff0c;可读写的全局变量在不同的js、页面中均可调用和读写 技术&#xff1a;使用vue的store 用法总结 一、定义变量 1、找到vue的/src/store路径&#xff0c;在modules文件夹下创建文件&#xff08;这里便于测试创建demo.js&…

51单片机入门:DS1302时钟

51单片机内部含有晶振&#xff0c;可以实现定时/计数功能。但是其缺点有&#xff1a;精度往往不高、不能掉电使用等。 我们可以通过DS1302时钟芯片来解决以上的缺点。 DS1302时钟芯片 功能&#xff1a;DS1302是一种低功耗实时时钟芯片&#xff0c;内部有自动的计时功能&#x…

SpringBoot启动流程源码解析

目录 一、SpringApplication构造方法解析 1. web应用类型 2. BootstrapRegistryInitializer 3. ApplicationContextInitializer 4. ApplicationListener 5. 推断Main方法所在类 二、SpringApplication.run(String... args)方法解析 1.创建DefaultBootstrapContext 2.获…

订单超时自动取消的实践方案

1、定时任务方案 方案流程&#xff1a; 每隔 30 秒查询数据库&#xff0c;取出最近的 N 条未支付的订单。 遍历查询出来的订单列表&#xff0c;判断当前时间减去订单的创建时间是否超过了支付超时时间&#xff0c;如果超时则对该订单执行取消操作。 定时任务方案工程实现相…