前言:
笔者目前在校本科大三,目标方向是人工智能、计算机视觉。上一个OpenCV学习笔记专栏已完结,在学习完OpenCV后,我继续学习C++,并用纯C++做UE4项目的方式继续提升自己的水平。
梁迪老师的水平非常高,他的课程本来也无需笔记:课程本身即为最好的笔记。但由于我天赋有限,还是边看边记,以防遗忘——知识点太多,步骤太繁杂了。在学习过程中,我也偶有思考,思索为什么某个方法老师要这样做。所以,一是为了记录,二是为了分享,才有了这个专栏。
内容方面,由于我在开启这个专栏时,此项目已经做完很多了。所以,前期的一些大篇幅叙述的知识,可能在后期应用中一带而过。以及,前期的一些知识,后期会重新剖析,并加上我的个人理解。
另外,若有学术交流/学业交流意愿,可以邮件联系1246210283@qq.com,希望一齐进步。
本篇学习内容:
13.读写Json文件
14.游戏菜单界面
13.读写Json文件
为了能在游戏关闭时保存上一次的语言、声音设置,我们需要读写游戏存档文件。
文件路径是SlAiCourse\Content\Res\ConfigData\RecordData.json
(一)准备工作
(1)准备一个基于模板的单例模式。这个单例模式类似于SlAiStyle,但是可以通过不同的类实例化不同的单例模式。在读写Json文件时,它可以实例化一个SlAiJsonHandle,然后执行其内的函数等。
(2)准备函数:根据enum类型获取字符串、根据字符串获取enum值。它们都是模板函数。
在DataHandle中:
template<typename TEnum>
FString GetNumValueAsString(const FString& Name, TEnum Value);
template<typename TEnum>
TEnum GetEnumValueFromString(const FString& Name, FString Value);
(3)对应RecordData.json中的内容,准备一些变量。
在DataHandle中:
public:
//语言
ECultureTeam CurrentCulture; //设置这个变量,是因为这个变量要传入下一个场景
//音量
float MusicVolume;
//音效
float SoundVolume;
//存档数据
TArray<FString> RecordDataList;
(4)在DataHandle中准备一个初始化存档数据的函数
void InitRecordData();
(二)读取Json文件
(1)在JsonHandle中:准备存档文件名和相对路径
private:
//存档文件名
FString RecordDataFileName;
//相对路径
FString RelativePath;
(2)准备三个函数。
public:
SlAiJsonHandle();
//解析Json文件 解析存档
void RecordDataJsonRead(FString& Culture, float& MusicVolume, float& SoundVolume, TArray<FString>& RecordDataList);
private:
//读取Json文件到字符串
bool LoadStringFromFile(const FString & FileName, const FString & RelaPath, FString& ResultString);
(3)实现这三个函数。
由于RecordDataJsonRead是public权限,这个函数是给DataHandle的InitRecordData()调用的。
而LoadStringFromFile函数是被RecordDataJsonRead调用的。
(4)实现根据enum类型获取字符串、根据字符串获取enum值函数
(5)实现InitRecordData()函数。
//获取语言
FString Culture;
//读取存档数据
SlAiSingleton<SlAiJsonHandle>::Get()->RecordDataJsonRead(Culture, MusicVolume, SoundVolume, RecordDataList);
//初始化语言
ChangeLocalizationCulture(GetEnumValueFromString<ECultureTeam>(FString("ECultureTeam"), Culture));
//输出一下 SanitizeFloat:把浮点数转为字符串
SlAiHelper::Debug(Culture + FString("--") + FString::SanitizeFloat(MusicVolume) + FString("--")+ FString::SanitizeFloat(SoundVolume),20.f);
//迭代器循环读取RecordDataList
for (TArray<FString>::TIterator It(RecordDataList); It; ++It) {
SlAiHelper::Debug(*It, 20.f);
}
这个函数在读取到存档中的数据后,将其一一赋值给DataHandle中的变量。这样就完成了Json文件的读取。
Json文件的写入和Json文件读取逻辑类似。
14.游戏菜单界面
首先写完进入游戏界面控件和选择存档界面控件。这两个控件的逻辑和之前的Widget逻辑大致相同。
我们通过动态修改MenuWidget下ContentBox的内容,即可进行菜单界面不同界面的转换。
如何动态修改MenuWidget下ContentBox的内容:
(1)枚举类:
namespace EMenuType
{
enum Type
{
None,
MainMenu,
StartGame,
GameOption,
NewGame,
ChooseRecord
};
}
(2)准备一个结构体:
struct MenuGroup
{
//菜单标题
FText MenuName;
//菜单高度
float MenuHeight;
//下属组件
TArray<TSharedPtr<SCompoundWidget>> ChildWidget;
//构造函数
MenuGroup(const FText Name, const float Height, TArray<TSharedPtr<SCompoundWidget>>* Children) {
MenuName = Name;
MenuHeight = Height;
for (TArray<TSharedPtr<SCompoundWidget>>::TIterator It(*Children); It; ++It) {
ChildWidget.Add(*It);
}
}
};
(3)这样一个MenuGroup就对应一个菜单界面。我们用MenuMap保存所有的菜单界面:
TMap<EMenuType::Type, TSharedPtr<MenuGroup>> MenuMap;
(4)对于会产生变化的界面,用指针维护:
//游戏设置Widget的指针
TSharedPtr<SSlAiGameOptionWidget> GameOptionWidget;
//新游戏控件指针
TSharedPtr<SSlAiNewGameWidget> NewGameWidget;
//选择存档控件指针
TSharedPtr<SSlAiChooseRecordWidget> ChooseRecordWidget;
(5)写一个函数来初始化所有的菜单界面。
void InitializeMenuList();
(6)写一个函数来进行界面选择。
void ChooseWidget(EMenuType::Type WidgetType);
注意,在写完该函数后,回到InitializeMenuList()函数下设置初始化界面为主菜单。
本文介绍了在C++中使用UE4进行游戏开发时,如何读写Json文件以保存游戏设置,如语言和音量。通过单例模式处理Json操作,并展示了如何根据枚举类型转换字符串。此外,文章还阐述了创建游戏菜单界面的步骤,包括动态切换不同界面的方法。
2373

被折叠的 条评论
为什么被折叠?



