十五、UI音乐播放与调节
实现音乐播放,半实现进入游戏与加载存档
声明资源
SlAiMenuWidgetStyle.h
#include"SlateSound.h"
...
/*
* 开始游戏声音
*/
UPROPERTY(EditAnywhere, Category = Sound)
FSlateSound StartGameSound;
/*
* 结束游戏声音
*/
UPROPERTY(EditAnywhere, Category = Sound)
FSlateSound ExitGameSound;
/*
* 转换按钮声音
*/
UPROPERTY(EditAnywhere, Category = Sound)
FSlateSound MenuItemChangeSound;
/*
* Menu背景声音
*/
UPROPERTY(EditAnywhere, Category = Sound)
FSlateSound MenuBackgroundMusic;
实时处理声音数据
调整音量是会实时更新。
SlAiHelper.h
#include"SlateApplication.h"
#include"TimerManager.h"
namespace SlAiHelper {
//播放声音并且延时调用UserClass的某个函数
template<class UserClass>
FORCEINLINE FTimerHandle PlaySoundAndCall(UWorld* World, const FSlateSound Sound,
UserClass* InUserObject, typename FTimerDelegate::TRawMethodDelegate<UserClass>::FMethodPtr InMethod)
{
FSlateApplication::Get().PlaySound(Sound);
FTimerHandle Result;
const float SoundDuration = FMath::Max(FSlateApplication::Get().GetSoundDuration(Sound), 0.1f);
FTimerDelegate Callback;
Callback.BindRaw(InUserObject, InMethod);
World->GetTimerManager().SetTimer(Result, Callback, SoundDuration, false);
return Result;
}
}
SlAiDataHandle.h
public:
//修改菜单音量
void ResetMenuVolume(float MusicVal, float SoundVal);
//初始化Menu声音数据
void InitializeMenuAudio();
private:
//保存Menu的声音
TMap<FString, TArray<class USoundCue*>> MenuAudioResource;
};
SlAiDataHandle.cpp
...
#include"Sound/SoundCue.h"
SlAiDataHandle::SlAiDataHandle()
{
//初始化存档数据
InitRecordData();
//初始化Menu声音数据
InitializeMenuAudio();
}
void SlAiDataHandle::ResetMenuVolume(float MusicVal, float SoundVal)
{
if (MusicVal > 0)
{
MusicVolume = MusicVal;
//循环设置背景音乐
for (TArray<USoundCue*>::TIterator It(MenuAudioResource.Find(FString("Music"))->CreateIterator()); It; ++It)
{
//设置音量
(*It)->VolumeMultiplier = MusicVolume;
}
}
if (SoundVal > 0)
{
SoundVolume = SoundVal;
//循环设置音效
for (TArray<USoundCue*>::TIterator It(MenuAudioResource.Find(FString("Sound"))->CreateIterator()); It; ++It)
{
//指针的指针
(*It)->VolumeMultiplier = SoundVolume;
}
}
//更新存档数据
SlAiSingleton<SlAiJsonHandle>::Get()->UpdateRecordData(GetEnumValueAsString<ECultureTeam>(FString("ECultureTeam"),
CurrentCulture), MusicVolume, SoundVolume, &RecordDataList);
}
...
void SlAiDataHandle::InitializeMenuAudio()
{
//添加资源文件到资源列表
TArray<USoundCue*> MusicList;
MusicList.Add(Cast<USoundCue>(SlAiStyle::GetMenuStyle()->MenuBackgroundMusic.GetResourceObject()));
TArray<USoundCue*> SoundList;
SoundList.Add(Cast<USoundCue>(SlAiStyle::GetMenuStyle()->StartGameSound.GetResourceObject()));
SoundList.Add(Cast<USoundCue>(SlAiStyle::GetMenuStyle()->ExitGameSound.GetResourceObject()));
SoundList.Add(Cast<USoundCue>(SlAiStyle::GetMenuStyle()->MenuItemChangeSound.GetResourceObject()));
//添加资源到Map
MenuAudioResource.Add(FString("Music"), MusicList);
MenuAudioResource.Add(FString("Sound"), SoundList);
//重置一下声音
ResetMenuVolume(MusicVolume, SoundVolume);
}
退出游戏,半实现进入游戏,加载存档
新地图未创建
...
private:
//退出游戏
void QuitGame();
//进入游戏
void EnterGame();
};
...
#include"SlAiMenuController.h"
#include"Kismet/GameplayStatics.h"
#include"SlAiHelper.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlAiMenuWidget::Construct(const FArguments& InArgs)
{
//播放背景音乐
FSlateApplication::Get().PlaySound(SlAiStyle::GetMenuStyle()->MenuBackgroundMusic);
InitializeMenuList();
InitializeAnimation();
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlAiMenuWidget::MenuItemOnClicked(EMenuItem::Type ItemType)
{
...
case EMenuItem::QuitGame:
//退出游戏,播放声音并且延时调用退出函数
SlAiHelper::PlaySoundAndCall(UGameplayStatics::GetPlayerController(GWorld, 0)->GetWorld(), SlAiStyle::GetMenuStyle()->ExitGameSound, this, &SSlAiMenuWidget::QuitGame);
...
case EMenuItem::EnterGame:
SlAiHelper::PlaySoundAndCall(UGameplayStatics::GetPlayerController(GWorld, 0)->GetWorld(),
SlAiStyle::GetMenuStyle()->StartGameSound, this, &SSlAiMenuWidget::EnterGame);
break;
case EMenuItem::EnterRecord:
SlAiHelper::PlaySoundAndCall(UGameplayStatics::GetPlayerController(GWorld, 0)->GetWorld(),
SlAiStyle::GetMenuStyle()->StartGameSound, this, &SSlAiMenuWidget::EnterGame);
break;
}
}
void SSlAiMenuWidget::ChangeCulture(ECultureTeam Culture)
{
SlAiDataHandle::Get()->ChangeLocalzationCulture(Culture);
}
void SSlAiMenuWidget::ChangVolume(const float MusicVal, const float SoundVal)
{
SlAiDataHandle::Get()->ResetMenuVolume(MusicVal, SoundVal);
}
void SSlAiMenuWidget::PlayClose(EMenuType::Type NewMenu)
{
//设置新的界面
CurrentMenu = NewMenu;
//设置新高度
CurrentHeight = (*MenuMap.Find(NewMenu))->MenuHeight;
//设置播放状态是Close
AnimState = EMenuAnim::Close;
//播放反向动画
MenuAnimation.PlayReverse(this->AsShared());
//播放切换菜单音乐
FSlateApplication::Get().PlaySound(SlAiStyle::GetMenuStyle()->MenuItemChangeSound);
}
//退出游戏
void SSlAiMenuWidget::QuitGame()
{
Cast<ASlAiMenuController>(UGameplayStatics::GetPlayerController(GWorld, 0))->ConsoleCommand("quit");
}
//进入游戏
void SSlAiMenuWidget::EnterGame()
{
SlAiHelper::Debug(FString("EnterGame"), 10.f);
//解锁按钮
ControlLocked = false;
}
点击进入存档后打印EnterGame