当前位置: 首页 > news >正文

47. UE5 RPG 实现角色死亡效果

在上一篇文章中,我们实现了敌人受到攻击后会播放受击动画,并且还给角色设置了受击标签。并在角色受击时,在角色身上挂上受击标签,在c++里,如果挂载了此标签,速度将降为0 。
受击有了,接下来我们将实现角色的死亡逻辑,角色血量为0或者小于0时,我们将触发它的死亡功能。

实现死亡

在战斗接口类里增加一个虚函数,=0 是我们无法创建函数的实现,必须在子类里面去覆写它。

virtual void Die() = 0;

在角色基类里面覆写

virtual void Die() override;

接着我们增加一个在每个客户端上执行的函数,被Die函数调用。
NetMulticast设置后,这个函数被调用时,将在服务器执行,然后复制到每个客户端。和它对应的还有(Server:只在服务器运行,Client:只在调用此函数的客户端运行)这种情况的函数实现需要在后面加上_Implementation
Reliable: 这是一个传输属性,表示该函数的数据应该以可靠的方式发送。

	UFUNCTION(NetMulticast, Reliable)virtual void MulticastHandleDeath();

这样Die函数只会在服务器调用,我们将只需要服务器调用的函数写到此函数内
比如武器分离,然后调用每个端都会运行的函数MulticastHandleDeath()

void ACharacterBase::Die()
{//将武器从角色身上分离Weapon->DetachFromComponent(FDetachmentTransformRules(EDetachmentRule::KeepWorld, true));MulticastHandleDeath();
}

在MulticastHandleDeath()函数里,我们开启武器和角色的模拟效果,并关闭碰撞体的碰撞,防止它影响武器和角色

void ACharacterBase::MulticastHandleDeath_Implementation()
{//开启武器物理效果Weapon->SetSimulatePhysics(true); //开启模拟物理效果Weapon->SetEnableGravity(true); //开启重力效果Weapon->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); //开启物理碰撞通道//开启角色物理效果GetMesh()->SetSimulatePhysics(true); //开启模拟物理效果GetMesh()->SetEnableGravity(true); //开启重力效果GetMesh()->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); //开启物理碰撞通道GetMesh()->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block); //开启角色与静态物体产生碰撞//关闭角色碰撞体碰撞通道,避免其对武器和角色模拟物理效果产生影响GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
}

在敌人里面,我们需要额外实现一些内容,就是小怪死亡后,我们要在一定时间后将其清除掉。

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Combat")float LifeSpan = 5.f; //设置死亡后的存在时间

在敌人基类里面也覆盖Die函数,并在死亡时设置它的清除时间

void AEnemyBase::Die()
{SetLifeSpan(LifeSpan);Super::Die();
}

接下来在AttributeSet的PostGameplayEffectExecute函数里,增加Die函数调用的逻辑处理,我们在死亡时调用即可

	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){//调用死亡函数ICombatInterface* CombatInterface = Cast<ICombatInterface>(Props.TargetAvatarActor);if(CombatInterface){CombatInterface->Die();}}else{//激活受击技能FGameplayTagContainer TagContainer;TagContainer.AddTag(FMyGameplayTags::Get().Effects_HitReact);Props.TargetASC->TryActivateAbilitiesByTag(TagContainer); //根据tag标签激活技能}}}

接着可以编译运行,我们攻击敌人,查看它死亡时是否能够模拟布娃娃效果,并且在设置的清除时间后,被正确清除
在这里插入图片描述

溶解材质

死亡效果已经实现了,但是小怪死亡定时直接清除掉,显得太突兀,大部分游戏中的做法就是使用溶解效果来实现它的缓慢消失的效果。
所以我们需要一个溶解材质,在UE里面,我们可以通过连连看来实现蓝图类型的节点实现此功能。
首先,我们创建一个材质
在这里插入图片描述
我们需要一个透明裁剪的材质,将混合模式修改为已遮罩(Masked)
在这里插入图片描述
溶解需要一个值来控制它平滑的过渡,但是每个材质的溶解的范围不同,所以,我这里设置了两个值开始结束,然后用lerp实现从开始到结束的溶解过程。
在这里插入图片描述
然后从一张扰动图上面获取颜色进行对比度增强,获取到透明度值,我们可以通过修改溶解值来实现渐变过程。
在这里插入图片描述
CheapContrast是简单的调整对比度的节点函数,第一个传入颜色,第二个传入对比强度来获取增加对比度后的结果。
在这里插入图片描述
然后我们还需要一个就是溶解边缘发光的效果,这个将透明度作为UV的U去采样另外一张扰动图,然后增强对比度,获取到边缘设置到自发光上面实现效果。
在这里插入图片描述
材质我们设置了,如何查看放到模型上面的效果呢,我们可以在MI(材质实例)这里选择预览网格体进行查看
在这里插入图片描述
然后调整start和end的值,保证Dissolve能够在0的位置时没有溶解效果,而Dissolve值变为1时,角色被全部溶解掉
在这里插入图片描述

实现溶解效果

溶解材质我们有了,接下来就是如何实现从普通材质切换到溶解材质,并实现通过程序修改Dissolve溶解的数值。
我们打开敌人的骨骼网格体,发现它身上就一个材质,我们需要通过代码去实现切换模型的材质并实现对材质的属性修改。
在这里插入图片描述
打开角色基类,我们在里面增加两个参数,用于设置角色和武器的溶解材质

	UPROPERTY(EditAnywhere, BlueprintReadOnly)TObjectPtr<UMaterialInstance> DissolveMaterialInstance;UPROPERTY(EditAnywhere, BlueprintReadOnly)TObjectPtr<UMaterialInstance> WeaponDissolveMaterialInstance;

然后增加一个溶解函数,在角色死亡时调用

void Dissolve(); //溶解效果

溶解是需要一个时间过程,我准备在蓝图里面实现时间轴,这样比较方便,所以增加一个蓝图实现的函数,这个函数在代码里调用,在蓝图实现。参数我们设置了一个数组,因为不确定有几个材质需要修改,有可能只有一个角色的,有可能角色和武器两个,所以,我们直接传递数组去修改。

	UFUNCTION(BlueprintImplementableEvent)void StartDissolveTimeline(const TArray<UMaterialInstanceDynamic*>& DynamicMaterialInstance);

然后在溶解的实现这里,我们首先判断是否设置了对应的材质,如果设置了,则创建一个实例设置给角色,然后将材质添加到数组中,最后调用时间轴函数

void ACharacterBase::Dissolve()
{TArray<UMaterialInstanceDynamic*> MatArray;//设置角色溶解if(IsValid(DissolveMaterialInstance)){UMaterialInstanceDynamic* DynamicMatInst = UMaterialInstanceDynamic::Create(DissolveMaterialInstance, this);GetMesh()->SetMaterial(0, DynamicMatInst);MatArray.Add(DynamicMatInst);}//设置武器溶解if(IsValid(WeaponDissolveMaterialInstance)){UMaterialInstanceDynamic* DynamicMatInst = UMaterialInstanceDynamic::Create(WeaponDissolveMaterialInstance, this);Weapon->SetMaterial(0, DynamicMatInst);MatArray.Add(DynamicMatInst);}//调用时间轴渐变溶解StartDissolveTimeline(MatArray);
}

最后就是在死亡函数中,调用溶解

void ACharacterBase::MulticastHandleDeath_Implementation()
{//开启武器物理效果Weapon->SetSimulatePhysics(true); //开启模拟物理效果Weapon->SetEnableGravity(true); //开启重力效果Weapon->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); //开启物理碰撞通道//开启角色物理效果GetMesh()->SetSimulatePhysics(true); //开启模拟物理效果GetMesh()->SetEnableGravity(true); //开启重力效果GetMesh()->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); //开启物理碰撞通道GetMesh()->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block); //开启角色与静态物体产生碰撞//关闭角色碰撞体碰撞通道,避免其对武器和角色模拟物理效果产生影响GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);//设置角色溶解Dissolve();
}

代码部分我们已经完成了,接下来编译打开UE,在敌人基类里面覆写StartDissolveTimeline
在这里插入图片描述
创建一个时间轴
在这里插入图片描述
修改好名称,我们每次调用让其冲开始位置更新
在这里插入图片描述
双击时间轴打开,然后添加一个轨道,重新命一个名称
在这里插入图片描述
鼠标右键可以添加关键帧
在这里插入图片描述
添加完关键帧可以点击此处自动缩放
在这里插入图片描述
记得选中所有的点让其自动圆滑处理
在这里插入图片描述
处理完成,我们得到了一条圆滑的曲线时间轴
在这里插入图片描述
这样我们就完成了时间轴的制作。退出以后我们让时间轴去更新材质,这里有个小技巧就是可以增加线的固定点,让线不那么复杂
在这里插入图片描述
因为程序不知道材质里面的参数,所以,我们需要使用设置浮点型的参数
在这里插入图片描述
在材质上面,也显示了当前参数的类型,我们只需要将Dissolve修改从0到1就可以实现这个,在时间轴里面的值也是这么设置的。
在这里插入图片描述
我们只需要遍历数组设置对应的材质即可。
在这里插入图片描述
完成以后,我们需要在对应的敌人类里面去设置对应的角色和武器的材质
在这里插入图片描述
接下来就是运行测试效果了,如果效果正确,证明我们实现了对应的效果
在这里插入图片描述

相关文章:

47. UE5 RPG 实现角色死亡效果

在上一篇文章中&#xff0c;我们实现了敌人受到攻击后会播放受击动画&#xff0c;并且还给角色设置了受击标签。并在角色受击时&#xff0c;在角色身上挂上受击标签&#xff0c;在c里&#xff0c;如果挂载了此标签&#xff0c;速度将降为0 。 受击有了&#xff0c;接下来我们将…...

C语言/数据结构——每日一题(环形链表)

一.前言 今天在力扣上刷到一道链表题——环形链表https://leetcode.cn/problems/linked-list-cycle 想着和大家们分享一下。让我们直接开始今天的分享吧。、 二.正文 1.1题目描述 1.2题目分析 这道题是想让我们做出分析&#xff0c;该链表是不是带环链表&#xff0c;如果是…...

vue:网页icon无法显示

logo文件放在public文件夹下&#xff0c;在html里设置icon。 本地源码运行后发现网页icon无法显示我们设置的logo&#xff0c;而是显示了浏览器默认icon。 这个问题不需要解决&#xff0c;部署后网页icon显示就正常了。...

电脑设置在哪里打开?Window与Mac双系统操作指南

随着科技的不断发展&#xff0c;电脑已经成为我们日常生活和工作中不可或缺的一部分。然而&#xff0c;对于许多初学者来说&#xff0c;如何找到并熟悉电脑的设置界面可能是一个挑战。特别是对于那些同时使用Windows和Mac双系统的用户来说&#xff0c;更是需要一篇详尽的指南来…...

【linux】海量小文件的存储方案

在介绍海量文件存储之前&#xff0c;需要先介绍一下常见的系统里面文件是如何存储的 文件inode 在linux下&#xff0c;每个文件或者目录&#xff0c;都会分配一个inode(index node)&#xff0c;它不存储具体的文件内容&#xff0c;而是记录该文件的基础信息。每个inode大小一…...

【SpringBoot整合系列】SpringBoot整合RabbitMQ-基本使用

目录 SpringtBoot整合RabbitMQ1.依赖2.配置RabbitMQ的7种模式1.简单模式&#xff08;Hello World&#xff09;应用场景代码示例 2.工作队列模式&#xff08;Work queues&#xff09;应用场景代码示例手动 ack代码示例 3.订阅模式&#xff08;Publish/Subscribe&#xff09;应用…...

MySQL————创建存储过程函数

存储过程使用大纲 有参数传递 delimiter $$ 声明一个名称为get_student_introduce create procedure add_student_infor( in p_userName VARCHAR(20),in p_phone VARCHAR(11),in p_sex char(2),in p_introduce VARCHAR(255)) 开始操作 BEGIN 撰写真正在操作DMLDQL都行 INSE…...

数据赋能(86)——数据要素:管理核心框架

数据管理的核心框架是一个综合性的体系&#xff0c;旨在确保数据的有效利用、安全性以及合规性。这个框架主要包含了以下几个关键组成部分&#xff1a; 数据治理策略与目标&#xff1a;明确数据管理的整体战略和目标&#xff0c;包括数据价值的释放、数据资产地位的确定、多元…...

测试的基本概念

什么是软件测试 软件测试它就是一个过程测试就是对软件的全方位进行全面的校验.通过测试技术验证软件是不是符合用户的信息. 测试和开发的区别 在工作上的区别: 开发人员通过编程技能来开发和实现这个软件. 测试人员通过测试技能来验证软件是否符合用户需求. 在技术上的要求…...

Python多线程加速-休眠部分线程

总所周知Python由于GIL的问题&#xff0c;使用多线程时同一时刻只有一个线程在工作。故Python会在所有线程之间不断的切换&#xff0c;每切换到一个线程会执行一段字节码指令然后切换到另一个线程。如果开启了很多线程&#xff0c;且只有小部分线程在工作&#xff0c;如果不休眠…...

B+树(B+ Tree)

B树&#xff08;B Tree&#xff09;是一种对B树&#xff08;B-Tree&#xff09;的改进版本&#xff0c;它在数据库系统和文件系统中作为索引结构得到了广泛的应用&#xff0c;特别是在磁盘存储的场景下。B树保留了B树的基本特征&#xff0c;如自平衡、多路分支等&#xff0c;但…...

【Linux】了解信号产生的五种方式

文章目录 正文前的知识准备kill 命令查看信号man手册查看信号信号的处理方法 认识信号产生的5种方式1. 工具2. 键盘3. 系统调用kill 向任意进程发送任意信号raise 给调用方发送任意信号abort 给调用方发送SIGABRT信号 4. 软件条件5. 异常 正文前的知识准备 kill 命令查看信号 …...

【nuxt3国际化i18n】vue3+nuxt3+vite+TS国际化的正确做法

1、创建nuxt3请看Nuxt3官网 2、下面是添加i18n的叫教程&#xff0c;适用于企业前端项目。 添加依赖 依赖 yarn add vue-i18n yarn add nuxtjs/i18nnext -D配置文件nuxt.config.ts //nuxt.config.ts export default defineNuxtConfig({modules: [nuxtjs/i18n,],i18n: {stra…...

数据库管理-第185期 23ai:一套关系型数据干掉多套JSON存储(20240508)

数据库管理185期 2024-05-08 数据库管理-第185期 23ai:一套关系型数据干掉多套JSON存储&#xff08;20240508&#xff09;1 上期示例说明2 两个参数2.1 NEST/UNNEST2.2 CHECK/NOCHECK 3 一数多用3.1 以用户维度输出订单信息3.2 以产品维度3.3 以产品种类维度 4 美化输出总结 数…...

7 zip 介绍

7-Zip是一款广受好评的开源文件存档与压缩工具&#xff0c;支持高比率的压缩&#xff0c;适用于Windows、Linux和macOS等多种操作系统平台。以下是关于7-Zip的详细介绍&#xff1a; - **高压缩比**&#xff1a;7-Zip最显著的特点是其提供的高压缩率&#xff0c;尤其是使用其独…...

前端页面 贴边拖拽 盒子

vue 悬浮球(带自动吸附功能)_vue悬浮球-CSDN博客...

【408真题】2009-10

“接”是针对题目进行必要的分析&#xff0c;比较简略&#xff1b; “化”是对题目中所涉及到的知识点进行详细解释&#xff1b; “发”是对此题型的解题套路总结&#xff0c;并结合历年真题或者典型例题进行运用。 涉及到的知识全部来源于王道各科教材&#xff08;2025版&…...

WebSocket概述

TCP和HTTP规范有连接超时一说&#xff0c;所以长轮询并不能一直持续&#xff0c;服务端和客户端的连接需要定期的连接和关闭再连接。 WebSocket在请求头中有一个Connection:Upgrade字段&#xff0c;表示客户端想对协议进行升级&#xff0c;还有一个Upgrade:websocket字段&…...

人机协同是虚拟与真实的协同

“人机协同”是指人类与机器之间的合作与协同工作。在这种协同中&#xff0c;机器可以作为助手、辅助或扩展人类的能力&#xff0c;帮助人们完成任务&#xff0c;提高工作效率和质量。 虚拟与真实的协同是指在人机协同的过程中&#xff0c;虚拟想象世界和真实世界之间的协同。通…...

【编程向导】Docker-常用命令

常用命令 管理命令 管理命令说明builder管理构建config管理配置container管理容器context管理上下文engine管理引擎image管理镜像network管理网络node管理 Swarm 节点plugin管理插件secret管理 Docker secretsservice管理服务stack管理 Docker stacksswarm管理 Swarm 集群sys…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...