43. UE5 RPG 实现敌人血量显示条

在上一篇文章中,我们实现了火球术伤害功能,在火球击中敌方目标,可以降低敌人20的血量,这个值现在是固定的,后面我们会修改火球的伤害设置。接着,我们也测试了功能是实现的,但是在正常的游玩过程中,你不可能让玩家通过log界面获取敌人血量,这不符合玩家体验,所以,这一篇我们来实现在敌人的上方显示敌人剩余血量的UI。
为了实现敌人的血量条,我们首先将创建一个显示血量的用户控件,然后再敌人的基类里面实现在敌人血量变化时,对敌人的血量进行事件委托广播,来告知敌人修改血量。有个重点就是,我们自己定义的用户控件需要一个用户控件控制器作为中间媒介来获取数据,这里我们直接将敌人类作为控制器使用,没必要额外创建控制器。

在角色身上增加显示血条的UI组件

首先,我们要在敌人基类身上添加一个属性,用于配置使用的显示血条的用户控件

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Widget")TObjectPtr<UWidgetComponent> HealthBar;

接着在构造函数中,创建实例,并将其附加到根节点

	HealthBar = CreateDefaultSubobject<UWidgetComponent>("HealthBar");HealthBar->SetupAttachment(GetRootComponent()); //将血条附件到根节点上

接着编译打开UE,打开敌人的基类,我们通用的都会在基类身上设置,这样也会同步到子类身上,角色基类会出现我们创建的用户控件
在这里插入图片描述
在右侧的属性上,我们使用屏幕空间,然后以所需大小绘制,我们UI设置尺寸多大,它就按多大渲染。注意:每帧修改尺寸大小消耗极大,所以,我们使用它不要去修改大小,而是在内部去修改。
在这里插入图片描述
显示用的组件有了,我们还需要添加的用户控件,接下来,我们创建血条的UI控件。

创建基础血条

我们要创建一个敌人专门使用的进度条,这个进度条作为进度条的基础控件,里面可以设置一些通用的方法,用于以后扩展子类。
在这里插入图片描述
我们先在下方创建一个尺寸框,用于调节它的尺寸大小
在这里插入图片描述
将显示设置为所需,我们设置尺寸框多大,它就显示多大。然后将尺寸框设置为变量,并开启宽高和高度重载。
在这里插入图片描述
接着,我们实现使用变量控制它的宽高,使用节点重新控制它的宽高。编译以后,可以修改变量在构造时设置大小,选中节点右键折叠到函数,可以直接编译成一个函数。
在这里插入图片描述
接着,我们创建一个覆层,可以让下面的UI相互叠加,方便后面实现一个血条渐变的效果。
在这里插入图片描述
然后在覆层下面添加一个进度条
在这里插入图片描述
我们将进度条的背景填充的透明度设置为0,不使用它的背景色。
在这里插入图片描述
在外观这里修改将颜色修改为白色,我们将使用颜色去修改进度条颜色
在这里插入图片描述

将其设置为变量
在这里插入图片描述
我们在蓝图节点中设置它的样式,先将背景设置为透明,然后使用笔刷设置它的填充颜色
在这里插入图片描述
我们可以通过调整百分比查看它的进度,这个值我们将会在实现委托后,通过蓝图节点设置它。
在这里插入图片描述

创建委托

我们之前提到过,要将角色作为血条的控制器层使用,所以,我们接下来要在敌人基类身上增加委托实现对敌人血量和最大血量的广播。
回想一下,我们之前在设置主角属性面板时,我们创建了血量委托和蓝量委托,我们接着使用同样的方式实现。
在这里插入图片描述
我们在敌人基类里面增加血量的委托函数

	UPROPERTY(BlueprintAssignable)FOnAttributeChangedSignature OnHealthChanged;UPROPERTY(BlueprintAssignable)FOnAttributeChangedSignature OnMaxHealthChanged;

这里我们直接使用OverlayWidgetController里面的委托宏,所以,需要将OverlayWidgetController的文件引入

#include "UI/WidgetController/OverlayWidgetController.h"

接下来,我们就要实现对委托的广播,让它在合适的地方去广播,首先就是创建完成后,进行一次委托,用于初始化显示,接着就是绑定血量数值的变化,在数值变化时,及时更新数值。
首先,我们要将敌人的基类作为控制器设置给用户控件,可以在用户控件绑定对应监听,我们在初始化完成后,开始执行事件时,从用户控件组件中获取到用户控件,转换为我们创建的用户控件基类的实力,调用方法设置。这个方法会在设置后,触发设置回调

void AEnemyBase::BeginPlay()
{Super::BeginPlay();//初始化角色的ASCInitAbilityActorInfo();if(UMyUserWidget* UserWidget = Cast<UMyUserWidget>(HealthBar->GetUserWidgetObject())){UserWidget->SetWidgetController(this);}

我们将AttributeSet(AS)转换成我们自己创建的类型,这样我们可以获取到它的血量属性

	UAttributeSetBase* AS = Cast<UAttributeSetBase>(AttributeSet);if(AS){...

然后,我们通过ASC监听AS内的血量数值变化,绑定血量变化回调,在血量变动时,将会触发回调。由于进入游戏没有初始化,所以,我们需要进行初始化,设置它的初始值,在出生后,数值显示正确。

	if(UAttributeSetBase* AS = Cast<UAttributeSetBase>(AttributeSet)){//监听血量变化AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AS->GetHealthAttribute()).AddLambda([this](const FOnAttributeChangeData& Data){OnHealthChanged.Broadcast(Data.NewValue);});AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AS->GetMaxHealthAttribute()).AddLambda([this](const FOnAttributeChangeData& Data){OnMaxHealthChanged.Broadcast(Data.NewValue);});//初始化血量OnHealthChanged.Broadcast(AS->GetHealth());OnMaxHealthChanged.Broadcast(AS->GetMaxHealth());}

完整函数

void AEnemyBase::BeginPlay()
{Super::BeginPlay();//初始化角色的ASCInitAbilityActorInfo();if(UMyUserWidget* UserWidget = Cast<UMyUserWidget>(HealthBar->GetUserWidgetObject())){UserWidget->SetWidgetController(this);}if(const UAttributeSetBase* AS = Cast<UAttributeSetBase>(AttributeSet)){//监听血量变化AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AS->GetHealthAttribute()).AddLambda([this](const FOnAttributeChangeData& Data){OnHealthChanged.Broadcast(Data.NewValue);});AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AS->GetMaxHealthAttribute()).AddLambda([this](const FOnAttributeChangeData& Data){OnMaxHealthChanged.Broadcast(Data.NewValue);});//初始化血量OnHealthChanged.Broadcast(AS->GetHealth());OnMaxHealthChanged.Broadcast(AS->GetMaxHealth());}
}

创建敌人专用血条

我们上面创建了一个基础显示血条的用户控件,并且在敌人基类上实现了血量委托,接下来,我们将实现专门用于到敌人身上的血条。
我们创建一个新的控件蓝图,父类选择之前创建的基本的进度条。
在这里插入图片描述
有了敌人对应的控件后,我们首先去敌人蓝图基类去设置上
在这里插入图片描述
在用户控件事件里面,首先设置回调,将类型转换成敌人基类,这样,我们就可以使用控制器绑定回调了。
在这里插入图片描述
然后设置监听血量和最大血量广播,接着设置给进度条来实现血量减少变化。并且除以的时候我们使用Safe Divide节点,这个可以保证在除以0的时候不会报错。
在这里插入图片描述
为了通用,我们在它的父类创建一个设置百分比的,我们先将上层的设置百分比的实现,避免在子类里面每次都要去创建
在这里插入图片描述
在子类改成调用函数即可
在这里插入图片描述
接着可以运行测试了,我们发现功能实现了,血条的位置有点太靠中间了。
在这里插入图片描述
打开敌人基类蓝图,修改血条位置
在这里插入图片描述
现在显示正常。
在这里插入图片描述

添加逐渐消失的进度条

基础功能我们实现了,后面我们增加一些体验的功能,一个是受到攻击后,扣除血量,我们将显示一个逐渐过渡的条,能够让玩家清楚这一次攻击造成了多少伤害。
首先在进度条基类上面,增加额外的进度条这个进度条,这个进度条需要放在血条的上面,这样在覆层里面血条会优先显示。
在这里插入图片描述
接着将它修改名称,并设置为变量,修改对齐
在这里插入图片描述
记得将它的填充设置为白色。
在这里插入图片描述
使用蓝图节点修改它的颜色
在这里插入图片描述
然后修改完它的默认值以后,看一下最终效果
在这里插入图片描述
接下来,我们将实现逐渐消失进度条的效果,我们需要一个值,用于代表当前它所在的位置
在这里插入图片描述
它的默认值为1,就是默认满血
在这里插入图片描述
那么如何实现它平滑的过渡呢,我们使用Finterp To节点,这个节点需要我们传入一个当前值,和一个目标值,然后把时间传入,最后设置一下速度。我们只需要修改它的目标值,就可以实现缓慢的渐变效果。
在这里插入图片描述
将它折叠成函数,就实现了效果
在这里插入图片描述
如果创建的子类,在子类里面如果没有调用父类的帧回调,那它将不会执行,那么如何在子类里面去调用父类的帧回调呢,默认是不会调用的,右键找到节点的将调用添加到父函数,这样就可以生成一个调用父节点的帧回调事件的节点
在这里插入图片描述
在这里插入图片描述
现在我们还需要一个设置最终值的事件,我们创建一个自定义事件,在扣血以后,让它先显示一秒后,在逐渐消失
在这里插入图片描述
这个事件的调用,我们直接在修改了血量百分比这里设置即可。
在这里插入图片描述
接着运行测试,看看功能是否完成
在这里插入图片描述

设置血量条的显隐

接下来又是一个优化的效果,在游戏战斗中,我们不希望敌人的血量条一直显示,而是在被攻击后,将显示一段时间,这样不但可以节省性能,还能够让玩家清楚的知道攻击了哪些敌人。
敌人的血条默认将不会显示,在受到攻击后显示一段时间。
首先,我们增加一个函数,用于显示或隐藏,通过传入一个变量用于设置,并将此变量值记录下来,用于后面使用
在这里插入图片描述
首先,我们实现敌人创建后隐藏血条,那我们在构造完成,开始执行事件时,调用此函数隐藏
在这里插入图片描述
接下来是受伤显示,敌人受伤后,会触发血量回调,那我们可以在修改血量百分比的函数内调用显示
在这里插入图片描述
接下来是隐藏功能,我们需要一个定时器,在一定时间后,设置血条的隐藏,定时器也是无法在函数内使用的,那我们在设置血条渐变效果后面执行,在执行一个新的定时器时,一定要将旧的先清除,我们默认它显示6秒,如果6秒内定时器没有被清除,将触发事件,隐藏血条。
在这里插入图片描述
接下来就是变量的使用,我们设置显示隐藏时,设置了一个变量,这个变量可以用于,设置帧回调事件,可以节约性能,因为帧回调每帧都执行。
我们设置只有在显示时,才会执行帧回调。
在这里插入图片描述
接下来就是测试功能
在这里插入图片描述

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

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

相关文章

untiy avpro播放超过8K视频的解决方案

安转LAV Filters解码器&#xff0c;然后指定Avpro使用这个解码器播放即可 第一步 安装解码器 下载链接 第二步 AVPro设置 MediaPlayer脚本中一共两处

网络安全实训Day17and18

写在前面 第17和18天都讲的sql注入&#xff0c;故合并 ​​​​​​ 网络空间安全实训-渗透测试 Web渗透 定义 针对Web站点的渗透攻击&#xff0c;以获取网站控制权限为目的 Web渗透的特点 Web技术学习门槛低&#xff0c;更容易实现 Web的普及性决定了Web渗透更容易找到目…

C++之,static成员函数,友元函数以及内部类

个人主页&#xff1a;救赎小恶魔 欢迎大家来到小恶魔频道 好久不见&#xff0c;甚是想念 今天我们要深入讲述类与对象的初始化列表以及隐式类型转换 目录 引言&#xff1a; static成员函数 1. 概念 2.特性 友元 1.友元函数 2 友元类 内部类 匿名对象 引言&#xff…

杰发科技AC7840——ADC简介(1)_双路ADC同时使用

0. 简介 1. 特性 2. 双路ADC Sample里面没有双路的&#xff0c;以为那个规则组只有一个通道&#xff0c;看了外设寄存器才发现&#xff0c;原来他的通道是双路的。 注意1: ADC硬件引脚的配置 注意2: 规则组长度设置和 RSEQ序列号和CH通道号组合应该就对应了转换顺序&#xff0…

C语言Linux vim shell命令

无论是在插入模式或者是其他模式下对于文件的修改都是对于内存缓冲区进行修改&#xff0c;只有当点击w进行保存以后才会将数据写入到一个新的文件中的&#xff0c;将源文件删除&#xff0c;并且新文件改为文件的名字 1. actionmotion dG删到文件尾 ggdG先到开头再删除到末尾…

html+css+js+jquery实现在网页端将手动输入用户的信息转化成表格

1.实现的效果图 2.css代码 ​<style>*{background-color: antiquewhite;}#ss{font-size:20px;text-align: center;}#inputForm { margin-bottom: 20px; } #userTable { width: 100%; border-collapse: collapse; } #userTable th, #userTable td { border: 1px …

【uniapp/ucharts】采用 uniapp 框架的 h5 应用使用 ucharts(没有 uni_modules)

这种情况无法直接从 dcloud 平台上一键下载导入&#xff0c;所以应该在官网推荐的 git 仓库去单独下载&#xff1a; https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6/qiun-data-charts(%E9%9D%9Euni_modules) 下载的文件是如图所示的路径&…

攻防世界 easyphp

本题主要利用的知识点是php绕过 一、PHP代码分析 首先先看一下代码 我们需要利用get方式上传3个参数a,b,c&#xff0c;这3个分别需要满足不同的条件: a&#xff1a;设置a值&#xff1b;值大于6000000&#xff1b;长度不超过3&#xff1b; b&#xff1a;设置b值&#xff1b;MD…

【Qt】信号与槽

1 &#x1f351;信号和槽概述&#x1f351; 在 Qt 中&#xff0c;用户和控件的每次交互过程称为⼀个事件。⽐如 “⽤⼾点击按钮” 是⼀个事件&#xff0c;“⽤⼾关闭窗⼝” 也是⼀个事件。每个事件都会发出⼀个信号&#xff0c;例如⽤⼾点击按钮会发出 “按钮被点击” 的信号&…

websocket爬虫

人群看板需求分析 先找到策略中心具体的数据。对应数据库中的数据 看看接口是否需要被逆向 点开消费者细分&#xff0c;可以找到人群包&#xff08;人群名称&#xff09; 点击查看透视 label字段分类: 在这里插入图片描述 预测年龄&#xff1a;tagTitle 苹果id&#x…

微信小程序webview和小程序通讯

1.背景介绍 1.1需要在小程序嵌入vr页面&#xff0c;同时在vr页面添加操作按钮与小程序进行通信交互 1.2 开发工具&#xff1a;uniapp开发小程序 1.3原型图 功能&#xff1a;.点击体验官带看跳转小程序的体验官带看页面 功能&#xff1a;点击立即咨询唤起小程序弹窗打电话 2.…

RPA机器人怎么操作知乎好物推荐自动点击【添加】商品按钮?

先看需要实现的效果&#xff08;启动机器人-点击收益&#xff08;打开商品卡片列表&#xff09;-点击添加&#xff08;自动添加商品卡片到文章&#xff09;&#xff09;&#xff1a; 学员提问&#xff1a; 知乎上点击好物推荐【添加】商品按钮&#xff0c;iframe的元素是动态的…

表情识别 | 卷积神经网络(CNN)人脸表情识别(Matlab)

表情识别 | 卷积神经网络(CNN)人脸表情识别&#xff08;Matlab&#xff09; 目录 表情识别 | 卷积神经网络(CNN)人脸表情识别&#xff08;Matlab&#xff09;预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab使用卷积神经网络(CNN)&#xff0c;进行人脸表情情绪识别…

数据结构(九)---并查集

目录 1.集合 2.集合的相关操作 (1)查(Find)&#xff1a; •Find操作的优化 (2)并(Union)&#xff1a; •Union操作的优化 1.集合 数据元素之间的逻辑关系可以为集合&#xff0c;树形关系&#xff0c;线性关系&#xff0c;图关系。对于集合而言&#xff0c;一个集合可以划…

【嵌入式AI部署神经网络】STM32CubeIDE上部署神经网络之指纹识别(Pytorch)——篇一|环境搭建与模型初步部署篇

前言:本篇主要讲解搭建所需环境,以及基于pytorch框架在stm32cubeide上部署神经网络,部署神经网络到STM32单片机,本篇实现初步部署模型,没有加入训练集与验证集,将在第二篇加入。篇二详细讲解STM32CubeIDE上部署神经网络之指纹识别(Pytorch)的数据准备和模型训练过程等,…

Chrome 网络调试程序 谷歌网络调试 network

目录 1.网络面板总览2.概况了解3.Waterfall接口排队等待时间4.关注请求接口的Size,可能是占据内存溢出的接口5.过滤器一栏 fetch/xhr 什么意思6. Stalled 什么意思7.Queueing 什么意思8.Queueing和Stalled之间什么关系9.为什么会有阻塞状态10.Time列是pending 什么意思 1.网络面…

宏基因组|使用MEGAHIT组装

简介 MEGAHIT 是一款超快速且内存高效的下一代测序&#xff08;NGS&#xff09;组装工具&#xff0c;专门针对宏基因组进行了优化&#xff0c;同时在处理常规单个基因组&#xff08;小型或哺乳动物规模&#xff09;以及单细胞组装任务时也有出色表现。 主要特点与功能&#x…

node.js egg.js

Egg 是 Node.js 社区广泛使用的框架&#xff0c;简洁且扩展性强&#xff0c;按照固定约定进行开发&#xff0c;低协作成本。 在Egg.js框架中&#xff0c;ctx 是一个非常核心且常用的对象&#xff0c;全称为 Context&#xff0c;它代表了当前 HTTP 请求的上下文。ctx 对象封装了…

数据库和表创建练习

一丶要求 1.创建一个数据库db_classes 2 创建一行表db_hero 3. 将四大名著中的常见人物插入这个英雄表 二丶创建db_classes一个数据库, 使用数据库默认的字符集 create database db_classes; 三丶创建一行表db_hero 1.先切换到我们创建的db_classes;数据库中 use db_class…

怎么从回收站恢复已删除的文件?(5种恢复方法)

回收站是电脑操作系统中的一个特殊目录&#xff0c;用于存储被删除但尚未完全清除的文件和文件夹。当用户删除文件或文件夹时&#xff0c;它们并不立即从硬盘驱动器中移除&#xff0c;而是被移动到回收站。这样设计的目的是为了给用户一个“第二次机会”&#xff0c;如果他们意…