添加模板
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)));
}