40. UE5 RPG给火球术增加特效和音效

前面,我们将火球的转向和人物的转向问题解决了,火球术可以按照我们的想法朝向目标发射。现在,我们解决接下来的问题,在角色释放火球术时,会产生释放音效,火球也会产生对应的音效,在火球击中目标时,我们需要一个爆炸特效以及爆炸音效。

接下来,我们将一步步实现它们。

添加C++依赖

要在代码里面能够使用特效,我们需要在Build.cs里面增加它的依赖,在UE5里面,我们已经修改为使用Niagara粒子系统了。

PrivateDependencyModuleNames.AddRange(new string[] { "GameplayTags", "GameplayTasks", "NavigationSystem", "Niagara" });

添加击中特效和音效

我们增加两个可以设置的属性,分别用于设置击中特效和击中音效

UPROPERTY(EditAnywhere)
TObjectPtr<UNiagaraSystem> ImpactEffect;UPROPERTY(EditAnywhere)
TObjectPtr<USoundBase> ImpactSound;

增加一个私有函数,用于播放相关特效和音效

	void PlayImpact() const;

在函数实现这里,调用对应函数去播放

void AProjectile::PlayImpact() const
{//播放音效UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation(), FRotator::ZeroRotator);//播放粒子特效UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, ImpactEffect, GetActorLocation());
}

接下来增加一个变量,用于判断当前火球是否和其它物体产生了碰撞, 这个变量设置为私有即可

bool bHit;

接下里就是设置重叠回调,在重叠回调里面,我们要调用播放函数,然后判断对当前对象是否拥有权威性,如果拥有权威性,在触发重叠后,销毁它,如果没有,将bHit设置为true,代表它已经触发了重叠事件,并且已经播放了几种特效,但是没有对火球的控制权,无法自身直接销毁。

void AProjectile::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{PlayImpact();//在重叠后,销毁自身if(HasAuthority()){Destroy();}else{//如果对actor没有权威性,将bHit设置为true,证明当前已经播放了击中特效bHit = true;}
}

接着我们要重写销毁事件

virtual void Destroyed() override;

在销毁事件的实现这里,如果没有对火球的权威性控制权,并且现在还没有触发碰撞体的重叠事件,那么我们在销毁时播放击中特效。

void AProjectile::Destroyed()
{//如果没有权威性,并且bHit没有修改为true,证明当前没有触发Overlap事件,在销毁前播放击中特效if(!bHit && !HasAuthority()){PlayImpact();}Super::Destroyed();
}

编译代码,打开UE进行测试,首先将配置项设置上对应的Niagara粒子特效和音效
在这里插入图片描述
为了防止技能太快在没有创建火球之前被销毁,我们延迟0.5秒结束技能
在这里插入图片描述

运行,选择人物释放技能击中
在这里插入图片描述

添加技能释放音效

火球的击中特效我们制作出来了 ,接下来,我们实现一下技能释放时的音效,这个音效需要在蒙太奇里面添加,我们在角色释放技能的那一帧,给一个播放音效的通知。
打开释放技能的蒙太奇,在标准位置添加一个播放音效的通知
在这里插入图片描述
选中添加的通知,可以在右侧调整相关参数,我这里就添加一个声音
在这里插入图片描述

增加火球移动音效

现在释放火球有了音效,并且击中时有击中音效和击中特效,接下来我们添加一下火球在移动中,发出的音效,它是一个循环音效。
首先打开代码编辑器,添加一个用于添加音效文件的变量,然后添加一个存储生产的循环音效的变量,由于它是一直循环播放的,所以我们需要在Actor被销毁时,一同销毁掉这个音效组件。

//移动循环音效
UPROPERTY(EditAnywhere)
TObjectPtr<USoundBase> LoopingSound;//储存循环音效的变量,后续用于删除
UPROPERTY()
TObjectPtr<UAudioComponent> LoopingSoundComponent;

在Actor的事件开始回调时,添加一个附加在根组件的音效,这样可以让音效跟随组件移动。

void AProjectile::BeginPlay()
{Super::BeginPlay();Sphere->OnComponentBeginOverlap.AddDynamic(this, &AProjectile::OnSphereOverlap);//添加一个音效,并附加到根组件上面,在技能移动时,声音也会跟随移动LoopingSoundComponent = UGameplayStatics::SpawnSoundAttached(LoopingSound, GetRootComponent());
}

如果我们添加的是循环播放的音效,它无法被停止,所以,我们将在火球术结束时,将音效组件暂停。创建的附加音效默认会在音效播放完成或者暂停后自动销毁。

void AProjectile::PlayImpact() const
{//播放声效UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation(), FRotator::ZeroRotator);//播放粒子特效UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, ImpactEffect, GetActorLocation());//将音乐停止后会自动销毁LoopingSoundComponent->Stop();
}

接着编译打开UE,我们找到对应的音频文件,将其设置为默认循环,这样在停止之前,它会一直播放
在这里插入图片描述
然后将音效文件设置上去
在这里插入图片描述

设置火球的存在时间

如果火球没有击中任何内容,它将会一直存在,所以,我们需要实现设置它的存在时间,如果它在一定时间内没有击中任何物体,那它将会自行销毁。
首先创建一个私有属性,可以在面板修改它的存在时间,单位秒。

private://此物体的存在时间UPROPERTY(EditDefaultsOnly)float LifeSpan = 15.f;

然后在事件开始时设置它的生存时间,如果值设置为0,它的生存时间为无限

void AProjectile::BeginPlay()
{Super::BeginPlay();//设置此物体的存在时间SetLifeSpan(LifeSpan);...
}

完整代码

Projectile.h

// 版权归暮志未晚所有。#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Projectile.generated.h"class UNiagaraSystem;
class UProjectileMovementComponent;
class USphereComponent;UCLASS()
class AURA_API AProjectile : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesAProjectile();UPROPERTY(VisibleAnywhere)TObjectPtr<UProjectileMovementComponent> ProjectileMovement;protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;virtual void Destroyed() override;UFUNCTION()void OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
private://此物体的存在时间UPROPERTY(EditDefaultsOnly)float LifeSpan = 15.f;void PlayImpact() const;bool bHit;//碰撞球UPROPERTY(VisibleAnywhere)TObjectPtr<USphereComponent> Sphere;//击中粒子特效UPROPERTY(EditAnywhere)TObjectPtr<UNiagaraSystem> ImpactEffect;//击中音效UPROPERTY(EditAnywhere)TObjectPtr<USoundBase> ImpactSound;//移动循环音效UPROPERTY(EditAnywhere)TObjectPtr<USoundBase> LoopingSound;//储存循环音效的变量,后续用于删除UPROPERTY()TObjectPtr<UAudioComponent> LoopingSoundComponent;
};

Projectile.cpp

// 版权归暮志未晚所有。#include "Actor/Projectile.h"#include "NiagaraFunctionLibrary.h"
#include "Components/AudioComponent.h"
#include "Components/SphereComponent.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Kismet/GameplayStatics.h"// Sets default values
AProjectile::AProjectile()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = false;bReplicates = true; //服务器负责计算并更新Actor的状态,然后通过网络将这些更新复制到所有连接的客户端上。//初始化碰撞体Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");SetRootComponent(Sphere); //设置其为根节点,Sphere->SetCollisionEnabled(ECollisionEnabled::QueryOnly); //设置其只用作查询使用Sphere->SetCollisionResponseToChannels(ECR_Ignore); //设置其忽略所有碰撞检测Sphere->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Overlap); //设置其与世界动态物体产生重叠事件Sphere->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Overlap); //设置其与世界静态物体产生重叠事件Sphere->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap); //设置其与Pawn类型物体产生重叠事件//创建发射组件ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>("ProjectileMovement");ProjectileMovement->InitialSpeed = 550.f; //设置初始速度ProjectileMovement->MaxSpeed = 550.f; //设置最大速度ProjectileMovement->ProjectileGravityScale = 0.f; //设置重力影响因子,0为不受影响
}// Called when the game starts or when spawned
void AProjectile::BeginPlay()
{Super::BeginPlay();//设置此物体的存在时间SetLifeSpan(LifeSpan);Sphere->OnComponentBeginOverlap.AddDynamic(this, &AProjectile::OnSphereOverlap);//添加一个音效,并附加到根组件上面,在技能移动时,声音也会跟随移动LoopingSoundComponent = UGameplayStatics::SpawnSoundAttached(LoopingSound, GetRootComponent());
}void AProjectile::Destroyed()
{//如果没有权威性,并且bHit没有修改为true,证明当前没有触发Overlap事件,在销毁前播放击中特效if(!bHit && !HasAuthority()){PlayImpact();}Super::Destroyed();
}void AProjectile::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{PlayImpact();//在重叠后,销毁自身if(HasAuthority()){Destroy();}else{//如果对actor没有权威性,将bHit设置为true,证明当前已经播放了击中特效bHit = true;}
}void AProjectile::PlayImpact() const
{//播放声效UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation(), FRotator::ZeroRotator);//播放粒子特效UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, ImpactEffect, GetActorLocation());//将音乐停止后会自动销毁if(LoopingSoundComponent) LoopingSoundComponent->Stop();
}

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

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

相关文章

【深度学习】DDoS-Detection-Challenge aitrans2024 入侵检测,基于机器学习(深度学习)判断网络入侵

当了次教练&#xff0c;做了个比赛的Stage1&#xff0c;https://github.com/AItransCompetition/DDoS-Detection-Challenge&#xff0c;得了100分。 一些记录&#xff1a; 1、提交的flowid不能重复&#xff0c;提交的是非入侵的数量和数据flowid,看check.cpp可知。 2、Stage…

大数据入门——概念、工具等

目录 一、基本概念 1.大数据技术 2.大数据特点 3.常见概念 4.数据分析师、数据开发工程师 二、相关工具 三、应用场景 四、大数据业务流程及组织结构 一、基本概念 1.大数据技术 主要解决海量数据的采集、存储和分析计算问题 2.大数据特点 大量、高速、多样、价值、…

【六十】【算法分析与设计】用一道题目解决dfs深度优先遍历,dfs中节点信息,dfs递归函数模板进入前维护出去前回溯,唯一解的剪枝飞升返回值true

路径之谜 题目描述 小明冒充X星球的骑士,进入了一个奇怪的城堡。 城堡里边什么都没有,只有方形石头铺成的地面。 假设城堡地面是nn个方格。如下图所示。 按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着音走,也不能跳跃。每走到一个新方格,就要向正北 方和正西…

ESP32开发

目录 1、简介 1.1 种类 1.2 特点 1.3 管脚功能 1.4 接线方式 1.5 工作模式 2、基础AT指令介绍 2.1 AT指令类型 2.2 基础指令及其描述 2.3 使用AT指令需要注意的事 3、AT指令分类和提示信息 3.1 选择是否保存到Flash的区别 3.2 提示信息 3.3 其他会保存到Flash的A…

基础SQL DQL语句

基础查询 select * from 表名; 查询所有字段 create table emp(id int comment 编号,workno varchar(10) comment 工号,name varchar(10) comment 姓名,gender char(1) comment 性别,age tinyint unsigned comment 年龄,idcard char(18) comment 身份证号,worka…

排序算法:顺序查找

简介 顺序查找&#xff08;也称为线性查找&#xff09;是一种简单直观的搜索算法。按照顺序逐个比较列表或数组中的元素&#xff0c;直到找到目标元素或搜索完整个列表。 应用场景 数据集比较小&#xff0c;无需使用复杂的算法。数据集没有排序&#xff0c;不能使用二分查找…

书生·浦语大模型实战营(第二期):OpenCompass司南大模型评测实战

目录 大语言模型评测中的挑战如何评测大模型模型客观题&主观题提示词工程长文本评测OpenCompass评测流水线CompassHub&#xff1a;高质量评测基准社区 OpenCompass介绍作业&#xff1a;使用OpenCompass评测internlm2-chat-1_8b模型在C-Eval数据集上的性能准备阶段环境配置数…

html--canvas粒子球

<!doctype html> <html> <head> <meta charset"utf-8"> <title>canvas粒子球</title><link type"text/css" href"css/style.css" rel"stylesheet" /></head> <body><script…

element plus:tree拖动节点交换位置和改变层级

图层list里有各种组件&#xff0c;用element plus的tree来渲染&#xff0c;可以把图片等组件到面板里&#xff0c;面板是容器&#xff0c;非容器组件&#xff0c;比如图片、文本等&#xff0c;就不能让其他组件拖进来。 主要在于allow-drop属性的回调函数编写&#xff0c;要理清…

ElasticSearch笔记一

随着这个业务的发展&#xff0c;我们的数据量越来越庞大。那么传统的这种mysql的数据库就渐渐的难以满足我们复杂的业务需求了。 所以在微服务架构下一般都会用到一种分布式搜索的技术。那么今天呢我们就会带着大家去学习分布搜索当中最流行的一种ElasticSearch&#xff0c;Ela…

基于harris角点和RANSAC算法的图像拼接matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ....................................................................... I1_harris fu…

【洛谷 P8605】[蓝桥杯 2013 国 AC] 网络寻路 题解(图论+无向图+组合数学)

[蓝桥杯 2013 国 AC] 网络寻路 题目描述 X X X 国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包&#xff0c;为了安全起见&#xff0c;必须恰好被转发两次到达目的地。该包可能在任意一个节点产生&#xff0c;我们需要知道该网络中一共有多少种…

python基础知识三(运算符、while循环、for循环)

目录 运算符&#xff1a; 算术运算符&#xff1a; 比较运算符&#xff1a; 赋值运算符&#xff1a; 逻辑运算符&#xff1a; 位运算符&#xff1a; 成员运算符&#xff1a; while循环&#xff1a; 1. while循环的语法&#xff1a; 2. while循环的执行过程&#xff1a…

232 基于matlab的MIMO雷达模型下一种子空间谱估计方法

基于matlab的MIMO雷达模型下一种子空间谱估计方法&#xff0c;采用过估计的方法&#xff0c;避免了信源数估计的问题&#xff0c;对数据协方差矩阵进行变换&#xff0c;构造信号子空间投影矩阵和噪声子空间投影矩阵&#xff0c;不需要像经典的MUSIC一样对其进行特征分解&#x…

【笔试强训】数字统计|两个数组的交集|点击消除

一、数字统计 链接&#xff1a;[NOIP2010]数字统计_牛客题霸_牛客网 (nowcoder.com) 思路&#xff1a; 枚举数字拆分&#xff08;模10 除10&#xff09; &#x1f4a1; 当前数据范围为10^4可以用int类型解决&#xff0c;如果到了10^9就需要用long类型 代码实现&#xff1a; i…

实验七 智能手机互联网程序设计(微信程序方向)实验报告

请编写一个用户登录界面&#xff0c;提示输入账号和密码进行登录&#xff0c;要求在输入后登陆框显示为绿色&#xff1b; 二、实验步骤与结果&#xff08;给出对应的代码或运行结果截图&#xff09; index.wxml <view class"content"> <view class"a…

绝地求生:16款战术手套,你最钟爱哪一款?

大家好&#xff0c;我是闲游盒&#xff01; 喜迎PUBG七周年生日同时游戏里又迎来了一款新的战术手套&#xff0c;那么就让我们来回顾一下目前出游戏中的16款战术手套吧&#xff0c;看看你最中意的是哪一款&#xff1f; 1、MAZARIN1K 战术手套 2、SPAJKK 战术手套 3、SWAGGER 战…

C++笔记:C++中的重载

重载的概念 一.函数重载 代码演示例子&#xff1a; #include<iostream> using namespace std;//函数名相同&#xff0c;在是每个函数的参数不相同 void output(int x) {printf("output int : %d\n", x);return ; }void output(long long x) {printf("outp…

php 编译安装oracel扩展

第一步安装Oracle客户端 1&#xff0c;需要下载基础包和sdk oracle客户端下载链接&#xff1a;Oracle Instant Client Downloads for Linux x86-64 (64-bit) https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html 选择最新版本 versi…

11 JavaScript学习:事件

Html事件 HTML 中有很多事件可以用来与用户交互&#xff0c;以下是一些常见的 HTML 事件及其详细解释和举例&#xff1a; click 事件&#xff1a;当用户点击元素时触发。 <button onclick"myFunction()">点击我</button>dblclick 事件&#xff1a;当用…