[UE4入门笔记(5)] 13.读写Json文件 14.游戏菜单界面 --梁迪老师UE4纯C++Slate开发沙盒游戏

目录

        • 前言:
  • 本篇学习内容:
    • 13.读写Json文件
    • 14.游戏菜单界面

前言:

笔者目前在校本科大三,目标方向是人工智能、计算机视觉。上一个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()函数下设置初始化界面为主菜单。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部