十、读取Json文件

添加模板

build.cs

PublicDependencyModuleNames.AddRange(new string[] {
    
     "Core", "CoreUObject", "Engine", "InputCore", "Slate", "SlateCore" ,"Json","JsonUtilities"});


处理Json文件

SlAiJsonHandle.h

#pragma once

#include "CoreMinimal.h"
#include"SlAiTypes.h"
#include"Json.h"

/**
 * 
 */
class SLAICOURSE_API SlAiJsonHandle
{
    
    
public:
	SlAiJsonHandle();

	//解析存档方法
	void RecordDataJsonRead(FString& Culture,float& MusicVolume,float& SoundVolume,TArray<FString>& RecordDataList);

private:

	//读取Json文件到字符串
	bool LoadStringFromFile(const FString& FileName, const FString& RelaPath,FString& ResultString);

private:

	//存档文件名
	FString RecordDataFileName;

	//相对路径
	FString RelativePath;
};

SlAiJsonHandle.cpp

#include "SlAiJsonHandle.h"
#include"SlAiHelper.h"

SlAiJsonHandle::SlAiJsonHandle()
{
    
    
	RecordDataFileName = FString("RecordData.json");
	RelativePath = FString("Res/ConfigData/");
}

void SlAiJsonHandle::RecordDataJsonRead(FString& Culture, float& MusicVolume, float& SoundVolume, TArray<FString>& RecordDataList)
{
    
    
	FString JsonValue;
	LoadStringFromFile(RecordDataFileName, RelativePath, JsonValue);

	TArray<TSharedPtr<FJsonValue>> JsonParsed;
	TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonValue);
	if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
	{
    
    
		//获取数据
		Culture = JsonParsed[0]->AsObject()->GetStringField(FString("Culture"));
		MusicVolume = JsonParsed[1]->AsObject()->GetNumberField(FString("MusicVolume"));
		SoundVolume = JsonParsed[2]->AsObject()->GetNumberField(FString("SoundVolume"));

		//获取存档数据
		TArray<TSharedPtr<FJsonValue>> RecordDataArray = JsonParsed[3]->AsObject()->GetArrayField(FString("RecordData"));
		for (int i = 0; i < RecordDataArray.Num(); ++i)
		{
    
    
			FString RecordDataName = RecordDataArray[i]->AsObject()->GetStringField(FString::FromInt(i));
			RecordDataList.Add(RecordDataName);
		}
	}
	else
	{
    
    
		SlAiHelper::Debug(FString("Deserialize Failed"));
	}
}

bool SlAiJsonHandle::LoadStringFromFile(const FString& FileName, const FString& RelaPath, FString& ResultString)
{
    
    
	if (!FileName.IsEmpty()) {
    
    
		//获取绝对路径
		FString AbsoPath = FPaths::ProjectContentDir() + RelaPath + FileName;
		if (FPaths::FileExists(AbsoPath))
		{
    
    
			if (FFileHelper::LoadFileToString(ResultString, *AbsoPath))
			{
    
    
				return true;
			}
			else
			{
    
    
				//加载不成功
				SlAiHelper::Debug(FString("Load Error") + AbsoPath);
			}
		}
		else
		{
    
    
			//输出文件不存在
			SlAiHelper::Debug(FString("File Not Exist") + AbsoPath);
		}
	}
	return false;
}

处理数据

SlAiDataHandle.h

...


public:

	...
	//存档数据
	TArray<FString> RecordDataList;
	
private:

	...

	//根据enum类型获取字符串
	template<typename TEnum>
	FString GetEnumValueAsString(const FString& Name, TEnum Value);

	//根据字符串获取Enum值
	template<typename TEnum>
	TEnum GetEnumValueFromString(const FString& Name, FString Value);

	//初始化存档数据
	void InitRecordData();

...
};

SlAiDataHandle.cpp

...




SlAiDataHandle::SlAiDataHandle()
{
    
    
	//初始化存档数据
	InitRecordData();
}


...


template<typename TEnum>
inline FString SlAiDataHandle::GetEnumValueAsString(const FString& Name, TEnum Value)
{
    
    
	const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, *Name, true);
	if (!EnumPtr)
	{
    
    
		return FString("InValid");
	}
	return EnumPtr->GetEnumName((int32)Value);
}

template<typename TEnum>
inline TEnum SlAiDataHandle::GetEnumValueFromString(const FString& Name, FString Value)
{
    
    
	const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, *Name, true);
	if (!EnumPtr)
	{
    
    
		return TEnum(0);
	}
	//*FString(Value)类似于C语言中的字符数组
	return (TEnum)EnumPtr->GetIndexByName(FName(*FString(Value)));
}



void SlAiDataHandle::InitRecordData()
{
    
    
	//获取语言
	FString Culture;
	//读取存档数据
	SlAiSingleton<SlAiJsonHandle>::Get()->RecordDataJsonRead(Culture, MusicVolume, SoundVolume, RecordDataList);

	//初始化语言
	ChangeLocalzationCulture(GetEnumValueFromString<ECultureTeam>(FString("ECultureTeam"), Culture));


	//Debug
	SlAiHelper::Debug(Culture + FString("--") + FString::SanitizeFloat(MusicVolume)+FString("--")+
		FString::SanitizeFloat(SoundVolume));
	//循环读取RecordDataList
	for (TArray<FString>::TIterator It(RecordDataList); It; It++)
	{
    
    
		SlAiHelper::Debug(*It, 20.f);
	}
}

运行

在这里插入图片描述
在这里插入图片描述

注意

数据初始化位置

数据初始化方法InitRecordData()SlAiDataHandle的构造方法中实现,所以单例类SlAiDataHandle实例被初始化时 数据初始化。

SlAiDataHandle初始化位置在SlAiMenuWidget

void SSlAiMenuWidget::Construct(const FArguments& InArgs)
{
    
    
...
	
			SNew(SSlAiGameOptionWidget)
...
void SSlAiGameOptionWidget::Construct(const FArguments& InArgs)
{
    
    
	...

	//初始化CheckBox的样式
	StyleInitialize();
}
void SSlAiGameOptionWidget::StyleInitialize()
{
    
    
	...

	switch (SlAiDataHandle::Get()->CurrentCulture)
	...
}

数据初始化方法

void SlAiDataHandle::InitRecordData()
{
    
    
	//获取语言
	FString Culture;
	//读取存档数据
	SlAiSingleton<SlAiJsonHandle>::Get()->RecordDataJsonRead(Culture, MusicVolume, SoundVolume, RecordDataList);

	//初始化语言
	//Culture = JsonParsed[0]->AsObject()->GetStringField(FString("Culture"));
	ChangeLocalzationCulture(GetEnumValueFromString<ECultureTeam>(FString("ECultureTeam"), Culture));


	...

解析存档方法

void SlAiJsonHandle::RecordDataJsonRead(FString& Culture, float& MusicVolume, float& SoundVolume, TArray<FString>& RecordDataList)
{
    
    
//保存加载的文本文件
	FString JsonValue;
	LoadStringFromFile(RecordDataFileName, RelativePath, JsonValue);

//Json 值是一种可以是任何 Json 类型的结构。
//4个Json值
	TArray<TSharedPtr<FJsonValue>> JsonParsed;
	
	//TJsonReader是一个模板类
	使用JsonValue创建并初始化一个新实例。
	TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonValue);
	
	//将JsonReader传给JsonParsed
	//详细看源码
	if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
	{
    
    
		//获取数据
		//JsonParsed[0]->AsObject()将此值作为对象返回,如果这不是 Json 对象则抛出错误
		//GetStringField(FString("Culture"))以字符串形式获取名为 Culture 的字段(ZH)。
		Culture = JsonParsed[0]->AsObject()->GetStringField(FString("Culture"));
		//0.3
		MusicVolume = JsonParsed[1]->AsObject()->GetNumberField(FString("MusicVolume"));
		//0.3
		SoundVolume = JsonParsed[2]->AsObject()->GetNumberField(FString("SoundVolume"));

		//获取存档数据
		/*[
	{
		"0":"Default"
	},
	{
		"1":"RecordOne"
	},
]*/
		TArray<TSharedPtr<FJsonValue>> RecordDataArray = JsonParsed[3]->AsObject()->GetArrayField(FString("RecordData"));
		for (int i = 0; i < RecordDataArray.Num(); ++i)
		{
    
    
			FString RecordDataName = RecordDataArray[i]->AsObject()->GetStringField(FString::FromInt(i));
			
	//TArray<FString> RecordDataList;
	//{"Default","RecordOne"}
			RecordDataList.Add(RecordDataName);
		}
	}
	else
	{
    
    
		SlAiHelper::Debug(FString("Deserialize Failed"));
	}
}

读取Json

Json文件存在,将文本文件加载到 ResultString并返回true。

bool SlAiJsonHandle::LoadStringFromFile(const FString& FileName, const FString& RelaPath, FString& ResultString)
{
    
    
	if (!FileName.IsEmpty()) {
    
    
		//获取绝对路径
		FString AbsoPath = FPaths::ProjectContentDir() + RelaPath + FileName;
		if (FPaths::FileExists(AbsoPath))
		{
    
    
		//将文本文件加载到 ResultString。
			if (FFileHelper::LoadFileToString(ResultString, *AbsoPath))
			{
    
    
				return true;
			}
			else
			{
    
    
				//加载不成功
				SlAiHelper::Debug(FString("Load Error") + AbsoPath);
			}
		}
		else
		{
    
    
			//输出文件不存在
			SlAiHelper::Debug(FString("File Not Exist") + AbsoPath);
		}
	}
	return false;
}

获取文件的绝对路径

//获取绝对路径FPaths::ProjectDir() + Content/Res/ConfigData/RecordData.json
//FPaths::ProjectDir()返回 base directory
FString AbsoPath = FPaths::ProjectContentDir() + RelaPath + FileName;

根据enum类型获取字符串

template<typename TEnum>
inline FString SlAiDataHandle::GetEnumValueAsString(const FString& Name, TEnum Value)
{
    
    
	const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, *Name, true);
	if (!EnumPtr)
	{
    
    
		return FString("InValid");
	}
	return EnumPtr->GetEnumName((int32)Value);
}

根据字符串获取Enum值

template<typename TEnum>
inline TEnum SlAiDataHandle::GetEnumValueFromString(const FString& Name, FString Value)
{
    
    
	const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, *Name, true);
	if (!EnumPtr)
	{
    
    
		return TEnum(0);
	}
	return (TEnum)EnumPtr->GetIndexByName(FName(*FString(Value)));
}

Guess you like

Origin blog.csdn.net/m0_51032168/article/details/121478607