前言:
笔者目前在校本科大三,目标方向是人工智能、计算机视觉。上一个OpenCV学习笔记专栏已完结,在学习完OpenCV后,我继续学习C++,并用纯C++做UE4项目的方式继续提升自己的水平。
梁迪老师的水平非常高,他的课程本来也无需笔记:课程本身即为最好的笔记。但由于我天赋有限,还是边看边记,以防遗忘——知识点太多,步骤太繁杂了。在学习过程中,我也偶有思考,思索为什么某个方法老师要这样做。所以,一是为了记录,二是为了分享,才有了这个专栏。
内容方面,由于我在开启这个专栏时,此项目已经做完很多了。所以,前期的一些大篇幅叙述的知识,可能在后期应用中一带而过。以及,前期的一些知识,后期会重新剖析,并加上我的个人理解。
另外,若有学术交流/学业交流意愿,可以邮件联系1246210283@qq.com,希望一齐进步。
本篇学习内容:
55.SoundMix音量
56.玩家死亡
55.SoundMix音量
(1)在BluePrint下创建一个MusicClass: SlAiMusicClass、SlAiSoundClass;一个SoundMix:SlAiSoundMix
前两个可以看作是声音的组,后面的SoundMix可以对这两个声音的组进行调控。
(2)点开声音资源,给声音资源指定SoundClass
(3)点开SoundMix,添加SoundClass
(4)点开动作蓝图,给动作添加音效。其中Punch等,我们在C++里设置,当碰撞到物体时再添加音效。
(5)在HandObject中设置物品碰到物体时发出声音
//打到物体时的音效
class USoundWave* OverlaySound;
在构造函数绑定默认音效:
static ConstructorHelpers::FObjectFinder<USoundWave> StaticSound(TEXT("SoundWave'/Game/Res/Sound/GameSound/Punch.Punch'"));
OverlaySound = StaticSound.Object;
在其他文件的BeginPlay下修改OverlaySound:
注:构造函数找资源可以用ConstructorHelpers::FObjectFinder,也可以用LoadObject。但是在其他地方只能用LoadObject
OverlaySound = LoadObject<USoundWave>(NULL, TEXT("SoundWave'/Game/Res/Sound/GameSound/Axe.Axe'"));
(6)接下来修改音量
在DataHandle中:
public:
void ResetGameVolume(float MusicVol, float SoundVol);
private:
//初始化Game声音数据
void InitializeGameAudio();
//音乐组件
class USoundMix* SlAiSoundMix;
class USoundClass* SlAiMusicClass;
USoundClass* SlAiSoundClass;
class FAudioDevice* AudioDevice;
.cpp文件中:
void SlAiDataHandle::InitializeGameAudio()
{
//通过LoadObject获取混音器和音类,其实就是之前在UE4编辑器内创建的SoundMix和SoundClass
SlAiSoundMix = LoadObject<USoundMix>(NULL, TEXT("SoundMix'/Game/Blueprint/Sound/SlAiSoundMix.SlAiSoundMix'"));
SlAiMusicClass = LoadObject<USoundClass>(NULL, TEXT("SoundClass'/Game/Blueprint/Sound/SlAiMusicClass.SlAiMusicClass'"));
SlAiSoundClass = LoadObject<USoundClass>(NULL, TEXT("SoundClass'/Game/Blueprint/Sound/SlAiSoundClass.SlAiSoundClass'"));
//获取音乐设备
AudioDevice = GEngine->GetMainAudioDevice();
//推送混音器到设备
AudioDevice->PushSoundMixModifier(SlAiSoundMix);
//根据音量设置一次声音
ResetGameVolume(MusicVolume, SoundVolume);
}
void SlAiDataHandle::ResetGameVolume(float MusicVol, float SoundVol)
{
if (MusicVol > 0) {
MusicVolume = MusicVol;
//使用混音器来设置
AudioDevice->SetSoundMixClassOverride(SlAiSoundMix, SlAiMusicClass, MusicVolume, 1.f, 0.2f, false);
}
if (SoundVol > 0) {
SoundVolume = SoundVol;
//使用混音器来设置
AudioDevice->SetSoundMixClassOverride(SlAiSoundMix, SlAiSoundClass, SoundVolume, 1.f, 0.2f, false);
}
//更新存档数据
SlAiSingleton<SlAiJsonHandle>::Get()->UpdateRecordData(GetEnumValueAsString<ECultureTeam>(FString("ECultureTeam"), CurrentCulture),
MusicVolume, SoundVolume, &RecordDataList);
}
(7)刚刚写好的SlAiDataHandle::ResetGameVolume给SSlAiGameMenuWidget::ChangeVolume调用。
(8)在GameMode下播放背景音乐
GameMode的BeginPlay下:
//播放背景音乐
USoundWave* BGMusic = LoadObject<USoundWave>(NULL, TEXT("SoundWave'/Game/Res/Sound/GameSound/GameBG.GameBG"));
BGMusic->bLooping = true;
UGameplayStatics::PlaySound2D(GetWorld(), BGMusic);
56.玩家死亡
(1)在Character下:
public:
//播放死亡动画,返回播放时长
float PlayDeadAnim();
private:
//死亡动画资源
class UAnimationAsset* AnimDead;
.cpp中:
float ASlAiPlayerCharacter::PlayDeadAnim()
{
GetMesh()->PlayAnimation(AnimDead, false);
return AnimDead->GetMaxCurrentTime();
}
(2)在Controller下:
public:
//死亡
void PlayerDead();
private:
//死亡时间函数 给死亡时间委托绑定的
void DeadTimeOut();
//死亡时间委托
FTimerHandle DeadHandle;
void ASlAiPlayerController::PlayerDead()
{
//转换到第三视角
SPCharacter->ChangeView(EGameViewMode::Third);
//播放死亡动画,获取死亡时间
float DeadDuration = SPCharacter->PlayDeadAnim();
//锁住输入
LockedInput(true);
//添加定时器委托
FTimerDelegate TimerDelegate = FTimerDelegate::CreateUObject(this, &ASlAiPlayerController::DeadTimeOut);
GetWorld()->GetTimerManager().SetTimer(DeadHandle, TimerDelegate, DeadDuration, false);
}
void ASlAiPlayerController::DeadTimeOut()
{
//设置游戏暂停
SetPause(true);
//设置游戏模式为混合
SwitchInputMode(false);
//更新界面
ShowGameUI.ExecuteIfBound(CurrentUIType, EGameUIType::Lose);
//更新当前UI
CurrentUIType = EGameUIType::Lose;
//锁住输入
LockedInput(true);
}
(3)在PlayerState下调用上面写好的函数即可