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

本文介绍了在C++中使用UE4进行游戏开发时,如何读写Json文件以保存游戏设置,如语言和音量。通过单例模式处理Json操作,并展示了如何根据枚举类型转换字符串。此外,文章还阐述了创建游戏菜单界面的步骤,包括动态切换不同界面的方法。

前言:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值