6 - 音频与粒子系统入门
本文将初步介绍UE5中有关音频系统和粒子系统的内容,包括一些概念,如何通过C++播放声音,通过C++生成粒子等操作。
音频系统
UE5中的音频
游戏中通常包括以下两种类型的声音:
- 2D声音:不会考虑听者的距离和方向,通常用于播放音乐;
- 3D声音:根据玩家的位置调整音量高低和左右方向,通常用于播放音效。
UE5中的声音格式文件主要为.wav
和.mp3
。
音频资产
UE5中音频相关的资产和类如下:
- Sound Base:包含音频的资产,在C++/蓝图中用于引用可播放的音频文件。
- Sound Wave:继承自Sound Base,表示已导入UE5的音频文件。
- Sound Cue:继承自Sound Base,包含与衰减、循环播放、混合等音频相关的逻辑。
- Sound Class:可以将音频文件分组,并管理如音量、音调等设置。例如将所有音效分组到SFX声音类中,将所有对话分组到Dialog声音类中。
- Sound Attenuation:指定3D声音的衰减方式,例如在多远距离时开始降低音量,在多远距离时听不见等。
- Audio Component:用于Actor的组件,可以管理音频文件的播放和它们的属性。
Meta Sounds
UE5还新增了一个名叫Meta Sounds的新音频系统,允许开发者使用数字信号处理技术来创建声音。
详见MetaSounds in Unreal Engine。
操作音频
导入音频
在内容浏览器中新建一个Audio
文件夹,将音频文件拖进去,双击打开后发现有好多可编辑属性。这里主要关注音效Sound:
这里能调音频是否循环,音量,音调以及声音所属的类。接下来新建一个声音类Dodgeball
,让这个音频属于Dodgeball
类,这样就能通过声音类来编辑所属音频资产的属性了。
播放声音
首先在投射物的头文件中添加如下成员:
// 躲避球反弹时播放的声音
UPROPERTY(EditAnywhere, Category = Sound)
USoundBase* BounceSound;
然后在源文件中添加GameplayStatics
对象用到的头文件:
#include "Kismet/GameplayStatics.h"
最后在球反弹的时候调用GameplayStatics
对象的PlaySoundAtLocation()
播放弹跳的声音,条件是BounceSound
有效且NormalImpulse
足够大:
void ADodgeballProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp, FVector ImpulseNormal,
const FHitResult& HitResult)
{
// 播放反弹声音
if (BounceSound != nullptr && ImpulseNormal.Size() > 600.f)
{
UGameplayStatics::PlaySoundAtLocation(this, BounceSound, GetActorLocation(),
1.0f, FMath::RandRange(0.7f, 1.3f));
}
...
}
其中,PlaySoundAtLocation()
负责在指定位置播放一个3D声音,参数如下:
- WorldContextObject:世界上下文对象,这里传入this;
- SoundBase:要播放的声音;
- Location:声音的位置;
- VolumeMultiplier:音量的高低,例如2.0就会让音量变成2倍;
- PitchMultiplier:音调的高低,这里用[0.7 ~ 1.3]之间的随机数。
如果想要播放2D声音,可以使用GameplayStatics
对象的PlaySound2D()
方法。
最后编译代码,修改相应蓝图类即可。
音效衰减
注意到无论角色距离弹跳的躲避球有多远,声音总是以相同的音量播放。接下来添加音效衰减资产BounceAttenuation
,让球的音量随距离增加而衰减。
音效衰减资产的编辑画面(主要是音量的衰减)如下:
可以调整内部半径 Inner Radius(距离超过此半径时开始衰减)和衰减距离 Falloff Distance(超过此距离后听不到声音)。
更多关于音效衰减资产的信息详见:Sound Attenuation in Unreal Engine
接下来在投射球的蓝图类中添加对应属性:
// 躲避球反弹时音效的音效衰减
UPROPERTY(EditAnywhere, Category = Sound)
USoundAttenuation* BounceSoundAttenuation;
然后修改PlaySoundAtLocation
:
UGameplayStatics::PlaySoundAtLocation(this,
BounceSound,
GetActorLocation(),
1.0f,
FMath::RandRange(0.7f, 1.3f),
0.0f,
BounceSoundAttenuation);
其中新增了两个参数,声音开始的时间和声音衰减资产。
最后编译代码,更改蓝图类,应用成果。
播放BGM
需要使用Audio Component来播放BGM,因此要创建一个继承于Actor类的C++类MusicManager
。在头文件处添加如下属性:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
class UAudioComponent* AudioComponent;
在构造函数处编写如下代码:
AMusicManager::AMusicManager()
{
PrimaryActorTick.bCanEverTick = false;
AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("Music Component"));
}
然后基于此类创建对应的蓝图类BP_MusicManager
,配置要播放的BGM,然后拖到场景中就行了。并且Audio组件是循环播放的,也不需要考虑配置是否循环播放的问题。
粒子系统
粒子系统是许多粒子的几何,这些粒子可能具有不同的图像、形状、颜色和大小。UE5中有两种创建粒子系统的工具:Cascade和Niagara。其中Niagara是UE5新增的更新更复杂的粒子系统。
简单操作
要想在C++中使用粒子系统,得先在使用它的类上添加如下属性:
// 发生碰撞时产生的粒子特效
UPROPERTY(EditAnywhere, Category = Particles)
class UParticleSystem* HitParticles;
接下来需要调用GameplayStatics
对象中的SpawnEmitterAtLocation()
函数来生成粒子:
// 播放粒子
if (HitParticles != nullptr)
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), HitParticles, GetActorTransform());
}
其中,SpawnEmitterAtLocation()
的一种参数列表如下:
- World :粒子生成所处的世界,使用
GetWorld()
获取; - EmitterTemplate:
UParticleSystem*
,要生成的粒子系统; - SpawnTransform :粒子在世界空间中的变换信息;
此外,如果想要将一个粒子系统附加到Actor上,让它随Actor移动而移动,需要使用GameplayStatics
对象提供的SpawnEmitterAttached()
函数。
最后编译完代码,去对应蓝图类中设置要产生什么粒子就可以了:
参考资料
中文翻译:《UE5 C++ 游戏开发完全学习教程》
英文原版:《Elevating Game Experiences with UE5》