八、完成游戏设置控件
样式声明
/*
* Slider的背景Brush
*/
UPROPERTY(EditAnywhere, Category = GameOption)
FSlateBrush SliderBarBrush;
/*
* 指定Slider的样式
*/
UPROPERTY(EditAnywhere, Category = GameOption)
FSliderStyle SliderStyle;
数据处理
...
public:
...
//修改中英文
void ChangeLocalzationCulture(ECultureTeam Culture);
//修改菜单音量
void ResetMenuVolume(float MusicVal, float SoundVal);
public:
//当前语言
ECultureTeam CurrentCulture;
//音量
float MusicVolume;
float SoundVolume;
...
};
.cpp
...
SlAiDataHandle::SlAiDataHandle()
{
//初始化为中文
CurrentCulture = ECultureTeam::ZH;
//初始化音量
MusicVolume = 0.5f;
SoundVolume = 0.5f;
}
//改变语言
void SlAiDataHandle::ChangeLocalzationCulture(ECultureTeam Culture)
{
switch (Culture)
{
case ECultureTeam::EN:
FInternationalization::Get().SetCurrentCulture(TEXT("en"));
break;
case ECultureTeam::ZH:
FInternationalization::Get().SetCurrentCulture(TEXT("zh"));
break;
}
//赋值
CurrentCulture = Culture;
}
//设置音量
void SlAiDataHandle::ResetMenuVolume(float MusicVal, float SoundVal)
{
if (MusicVal > 0)
{
MusicVolume = MusicVal;
}
if (SoundVal > 0)
{
SoundVolume = SoundVal;
}
}
完成游戏设置界面
SlAiGameOptionWidget.h
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include"SlAiTypes.h"
//修改中英文委托
DECLARE_DELEGATE_OneParam(FChangeCulture,const ECultureTeam)
//修改音量委托
DECLARE_DELEGATE_TwoParams(FChangeVolume,const float,const float)
/**
*
*/
class SLAICOURSE_API SSlAiGameOptionWidget : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SSlAiGameOptionWidget)
{
}
SLATE_EVENT(FChangeCulture,ChangeCulture)
SLATE_EVENT(FChangeVolume,ChangeVolume)
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs);
private:
//统一设置样式
void StyleInitialize();
//中文CheckBox事件
void ZhCheckBoxStateChanged(ECheckBoxState NewState);
//英文CheckBox事件
void EnCheckBoxStateChanged(ECheckBoxState NewState);
//音量变化事件
void MusicSliderChanged(float Value);
void SoundSliderChanged(float Value);
private:
//获取CheckBox指针
TSharedPtr<class SCheckBox> EnCheckBox;
TSharedPtr<SCheckBox> ZhCheckBox;
//两个进度条
TSharedPtr<class SSlider> MuSlider; //背景音乐
TSharedPtr<SSlider> SoSlider; //音效
//进度条百分比
TSharedPtr<class STextBlock> MuTextBlock;
TSharedPtr<STextBlock> SoTextBlock;
//委托变量
FChangeCulture ChangeCulture;
FChangeVolume ChangeVolume;
};
.cpp
...
#include"Slider.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlAiGameOptionWidget::Construct(const FArguments& InArgs)
{
//获取委托
ChangeCulture = InArgs._ChangeCulture;
ChangeVolume = InArgs._ChangeVolume;
ChildSlot
[
SNew(SBox)
.WidthOverride(500.f)
.HeightOverride(300.f)
[
SNew(SOverlay)
+SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SImage)
.Image(&SlAiStyle::GetMenuStyle()->GameOptionBGBrush)
]
+SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.Padding(FMargin(50.f))
[
SNew(SVerticalBox)
//切换中英文
+SVerticalBox::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.FillHeight(1.f)
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.FillWidth(1.f)
[
//中文切换
SAssignNew(ZhCheckBox,SCheckBox)
.OnCheckStateChanged(this,&SSlAiGameOptionWidget::ZhCheckBoxStateChanged)
[
SNew(STextBlock)
.Font(SlAiStyle::GetMenuStyle()->Font_40)
.ColorAndOpacity(SlAiStyle::GetMenuStyle()->FontColor_Black)
.Text(NSLOCTEXT("SlAiMenu","Chinese","Chinese"))
]
]
+SHorizontalBox::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.FillWidth(1.f)
[
//英文切换
SAssignNew(EnCheckBox,SCheckBox)
.OnCheckStateChanged(this,&SSlAiGameOptionWidget::EnCheckBoxStateChanged)
[
SNew(STextBlock)
.Font(SlAiStyle::GetMenuStyle()->Font_40)
.ColorAndOpacity(SlAiStyle::GetMenuStyle()->FontColor_Black)
.Text(NSLOCTEXT("SlAiMenu","English","English"))
]
]
]
//背景音乐音量
+SVerticalBox::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.FillHeight(1.f)
[
SNew(SOverlay)
+SOverlay::Slot()
.HAlign(HAlign_Left)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Font(SlAiStyle::GetMenuStyle()->Font_40)
.ColorAndOpacity(SlAiStyle::GetMenuStyle()->FontColor_Black)
.Text(NSLOCTEXT("SlAiMenu","Music","Music"))
]
+SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(SBox)
.WidthOverride(240.f)
[
SNew(SOverlay)
+SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.Padding(FMargin(30.f,0.f))
[
SNew(SImage)
.Image(&SlAiStyle::GetMenuStyle()->SliderBarBrush)
]
+SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Center)
[
//进度条
SAssignNew(MuSlider,SSlider)
.Style(&SlAiStyle::GetMenuStyle()->SliderStyle)
.OnValueChanged(this,&SSlAiGameOptionWidget::MusicSliderChanged)
]
]
]
+SOverlay::Slot()
.HAlign(HAlign_Right)
.VAlign(VAlign_Center)
[
SAssignNew(MuTextBlock,STextBlock)
.Font(SlAiStyle::GetMenuStyle()->Font_40)
.ColorAndOpacity(SlAiStyle::GetMenuStyle()->FontColor_Black)
]
]
//游戏音效
+SVerticalBox::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.FillHeight(1.f)
[
SNew(SOverlay)
+SOverlay::Slot()
.HAlign(HAlign_Left)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Font(SlAiStyle::GetMenuStyle()->Font_40)
.ColorAndOpacity(SlAiStyle::GetMenuStyle()->FontColor_Black)
.Text(NSLOCTEXT("SlAiMenu","Sound","Sound"))
]
+SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(SBox)
.WidthOverride(240.f)
[
SNew(SOverlay)
+SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.Padding(FMargin(30.f,0.f))
[
SNew(SImage)
.Image(&SlAiStyle::GetMenuStyle()->SliderBarBrush)
]
+SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Center)
[
SAssignNew(SoSlider,SSlider)
.Style(&SlAiStyle::GetMenuStyle()->SliderStyle)
.OnValueChanged(this,&SSlAiGameOptionWidget::SoundSliderChanged)
]
]
]
+SOverlay::Slot()
.HAlign(HAlign_Right)
.VAlign(VAlign_Center)
[
SAssignNew(SoTextBlock,STextBlock)
.Font(SlAiStyle::GetMenuStyle()->Font_40)
.ColorAndOpacity(SlAiStyle::GetMenuStyle()->FontColor_Black)
]
]
]
]
];
//初始化CheckBox的样式
StyleInitialize();
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
//初始化CheckBox的样式
void SSlAiGameOptionWidget::StyleInitialize()
{
//设置ZhCheckBox样式
ZhCheckBox->SetUncheckedImage(&SlAiStyle::GetMenuStyle()->UnCheckedBoxBrush);
ZhCheckBox->SetUncheckedHoveredImage(&SlAiStyle::GetMenuStyle()->UnCheckedBoxBrush);
ZhCheckBox->SetUncheckedPressedImage(&SlAiStyle::GetMenuStyle()->UnCheckedBoxBrush);
ZhCheckBox->SetCheckedImage(&SlAiStyle::GetMenuStyle()->CheckedBoxBrush);
ZhCheckBox->SetCheckedHoveredImage(&SlAiStyle::GetMenuStyle()->CheckedBoxBrush);
ZhCheckBox->SetCheckedPressedImage(&SlAiStyle::GetMenuStyle()->CheckedBoxBrush);
//设置EnCheckBox样式
EnCheckBox->SetUncheckedImage(&SlAiStyle::GetMenuStyle()->UnCheckedBoxBrush);
EnCheckBox->SetUncheckedHoveredImage(&SlAiStyle::GetMenuStyle()->UnCheckedBoxBrush);
EnCheckBox->SetUncheckedPressedImage(&SlAiStyle::GetMenuStyle()->UnCheckedBoxBrush);
EnCheckBox->SetCheckedImage(&SlAiStyle::GetMenuStyle()->CheckedBoxBrush);
EnCheckBox->SetCheckedHoveredImage(&SlAiStyle::GetMenuStyle()->CheckedBoxBrush);
EnCheckBox->SetCheckedPressedImage(&SlAiStyle::GetMenuStyle()->CheckedBoxBrush);
//设置CheckBox是否被选中 样式
switch (SlAiDataHandle::Get()->CurrentCulture)
{
case ECultureTeam::EN:
EnCheckBox->SetIsChecked(ECheckBoxState::Checked);
ZhCheckBox->SetIsChecked(ECheckBoxState::Unchecked);
break;
case ECultureTeam::ZH:
ZhCheckBox->SetIsChecked(ECheckBoxState::Checked);
EnCheckBox->SetIsChecked(ECheckBoxState::Unchecked);
break;
}
MuSlider->SetValue(SlAiDataHandle::Get()->MusicVolume);
SoSlider->SetValue(SlAiDataHandle::Get()->SoundVolume);
MusicSliderChanged(SlAiDataHandle::Get()->MusicVolume);
SoundSliderChanged(SlAiDataHandle::Get()->SoundVolume);
}
void SSlAiGameOptionWidget::ZhCheckBoxStateChanged(ECheckBoxState NewState)
{
//设置被选中的框
ZhCheckBox->SetIsChecked(ECheckBoxState::Checked);
EnCheckBox->SetIsChecked(ECheckBoxState::Unchecked);
//告诉数据控制类转换为中文
//SlAiDataHandle::Get()->ChangeLocalzationCulture(ECultureTeam::ZH);
ChangeCulture.ExecuteIfBound(ECultureTeam::ZH);
}
void SSlAiGameOptionWidget::EnCheckBoxStateChanged(ECheckBoxState NewState)
{
//设置被选中的框
ZhCheckBox->SetIsChecked(ECheckBoxState::Unchecked);
EnCheckBox->SetIsChecked(ECheckBoxState::Checked);
//告诉数据控制类转换为中文
//SlAiDataHandle::Get()->ChangeLocalzationCulture(ECultureTeam::EN);
ChangeCulture.ExecuteIfBound(ECultureTeam::EN);
}
void SSlAiGameOptionWidget::MusicSliderChanged(float Value)
{
//显示百分比
MuTextBlock->SetText(FText::FromString(FString::FromInt(FMath::RoundToInt(Value * 100)) + FString("%")));
//修改音量
//SlAiDataHandle::Get()->ResetMenuVolume(Value, -1.f);
ChangeVolume.ExecuteIfBound(Value, -1.f);
}
void SSlAiGameOptionWidget::SoundSliderChanged(float Value)
{
//显示百分比
//修改音量
//SlAiDataHandle::Get()->ResetMenuVolume(-1.f, Value);
ChangeVolume.ExecuteIfBound(-1.f, Value);
}
SlAiMenuWidget.h
...
private:
...
//修改语言
void ChangeCulture(ECultureTeam Culture);
//修改音量
void ChangVolume(const float MusicVal, const float SoundVal);
...
};
.cpp
...
//将SSlAiGameOptionWidget插入ContentBox
ContentBox->AddSlot()
[
SNew(SSlAiGameOptionWidget)
.ChangeCulture(this,&SSlAiMenuWidget::ChangeCulture)
.ChangeVolume(this,&SSlAiMenuWidget::ChangVolume)
];
...
void SSlAiMenuWidget::ChangeCulture(ECultureTeam Culture)
{
SlAiDataHandle::Get()->ChangeLocalzationCulture(Culture);
}
void SSlAiMenuWidget::ChangVolume(const float MusicVal, const float SoundVal)
{
SlAiDataHandle::Get()->ResetMenuVolume(MusicVal, SoundVal);
}
设置好BPSlAiMenuStyle
运行
注意
实现两个滑动条的思路与修改中英文的思路类似
数据类型的转换
//浮点转整,整转字符串,字符串转文本......
SoTextBlock->SetText(FText::FromString(FString::FromInt(FMath::RoundToInt(Value * 100)) + FString("%")));
为了后面游戏中可以在SlAiMenuWidget(菜单)中使用SlAiGameOptionWidget(游戏设置)的改变语言与修改音量,需要在SlAiGameOptionWidget中声明两个委托。
...
//修改中英文委托
DECLARE_DELEGATE_OneParam(FChangeCulture,const ECultureTeam)
//修改音量委托
DECLARE_DELEGATE_TwoParams(FChangeVolume,const float,const float)
...
SLATE_BEGIN_ARGS(SSlAiGameOptionWidget)
{
}
SLATE_EVENT(FChangeCulture,ChangeCulture)
SLATE_EVENT(FChangeVolume,ChangeVolume)
SLATE_END_ARGS()
...
//委托变量
FChangeCulture ChangeCulture;
FChangeVolume ChangeVolume;
将之前的方法改为
void SSlAiGameOptionWidget::ZhCheckBoxStateChanged(ECheckBoxState NewState)
{
...
//告诉数据控制类转换为中文
//SlAiDataHandle::Get()->ChangeLocalzationCulture(ECultureTeam::ZH);
ChangeCulture.ExecuteIfBound(ECultureTeam::ZH);
}
void SSlAiGameOptionWidget::EnCheckBoxStateChanged(ECheckBoxState NewState)
{
...
//告诉数据控制类转换为中文
//SlAiDataHandle::Get()->ChangeLocalzationCulture(ECultureTeam::EN);
ChangeCulture.ExecuteIfBound(ECultureTeam::EN);
}
void SSlAiGameOptionWidget::MusicSliderChanged(float Value)
{
...
//修改音量
//SlAiDataHandle::Get()->ResetMenuVolume(Value, -1.f);
ChangeVolume.ExecuteIfBound(Value, -1.f);
}
void SSlAiGameOptionWidget::SoundSliderChanged(float Value)
{
...
//修改音量
//SlAiDataHandle::Get()->ResetMenuVolume(-1.f, Value);
ChangeVolume.ExecuteIfBound(-1.f, Value);
}
在SlAiMenuWidget中绑定
...
ContentBox->AddSlot()
[
SNew(SSlAiGameOptionWidget)
.ChangeCulture(this,&SSlAiMenuWidget::ChangeCulture)
.ChangeVolume(this,&SSlAiMenuWidget::ChangVolume)
];
...
void SSlAiMenuWidget::ChangeCulture(ECultureTeam Culture)
{
SlAiDataHandle::Get()->ChangeLocalzationCulture(Culture);
}
void SSlAiMenuWidget::ChangVolume(const float MusicVal, const float SoundVal)
{
SlAiDataHandle::Get()->ResetMenuVolume(MusicVal, SoundVal);
}
以切换中英文为例
选择英文时,改变CheckBox状态
会按顺序执行以下代码
OnCheckStateChanged(this,&SSlAiGameOptionWidget::EnCheckBoxStateChanged)
void SSlAiGameOptionWidget::EnCheckBoxStateChanged(ECheckBoxState NewState)
{
//设置被选中的框
ZhCheckBox->SetIsChecked(ECheckBoxState::Unchecked);
EnCheckBox->SetIsChecked(ECheckBoxState::Checked);
//告诉数据控制类转换为中文
//SlAiDataHandle::Get()->ChangeLocalzationCulture(ECultureTeam::EN);
ChangeCulture.ExecuteIfBound(ECultureTeam::EN);
}
void SSlAiMenuWidget::ChangeCulture(ECultureTeam Culture)
{
SlAiDataHandle::Get()->ChangeLocalzationCulture(Culture);
}
void SlAiDataHandle::ChangeLocalzationCulture(ECultureTeam Culture)
{
switch (Culture)
{
case ECultureTeam::EN:
FInternationalization::Get().SetCurrentCulture(TEXT("en"));
break;
case ECultureTeam::ZH:
FInternationalization::Get().SetCurrentCulture(TEXT("zh"));
break;
}
//赋值
CurrentCulture = Culture;
}