上一篇只是将一个Json文件加载进内存,并没有对文件进行解析,接下来写一个解析Json文件的方法,把文件的中的字符串解析成我们所需要的数据资源
首先将SlAiSingleton.cpp中的内容都放置到 SlAiSingleton.h 中
d:\ue4 project\ue26.2\courseproject\slaicourse\Source\SlAiCourse\Public\Data\SlAiSingleton.h
1 #include "CoreMinimal.h"
2
3 /**
4 *
5 */
6 template<class T>
7 class SLAICOURSE_API SlAiSingleton
8 {
9 public:
10 static TSharedPtr<T> Get();
11
12 private:
13
14 static void Initialize();
15
16 static TSharedRef<T> Create();
17
18 private:
19 static TSharedPtr<T> TInstance;
20
21 };
22
23
24 template<class T>
25 TSharedPtr<T> SlAiSingleton<T>::TInstance = NULL;
26
27 //创建一个共享的引用
28 template<class T>
29 TSharedRef<T> SlAiSingleton<T>::Create()
30 {
31 TSharedRef<T> TRef = MakeShareable(new T());
32 return TRef;
33 }
34
35 template<class T>
36 void SlAiSingleton<T>::Initialize()
37 {
38 //判断指针是否存在,如果不存在则Cteate一个
39 if (!TInstance.IsValid())
40 {
41 TInstance = Create();
42 }
43 }
44
45 template<class T>
46 TSharedPtr<T> SlAiSingleton<T>::Get()
47 {
48 Initialize();
49 return TInstance;
50 }
d:\ue4 project\ue26.2\courseproject\slaicourse\Source\SlAiCourse\Private\Data\SlAiSingleton.cpp
SlAiSingleton.cpp 文件中则没有内容
1 #include "Data/SlAiSingleton.h"
解析Json文件相关内容
D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Public\Data\SlAiJsonHandle.h
1 #include "CoreMinimal.h"
2 #include "SlAiTypes.h"
3 #include "Json.h"
4
5
6 /**
7 *
8 */
9 class SLAICOURSE_API SlAiJsonHandle
10 {
11 public:
12 SlAiJsonHandle();
13
14 /**
15 * 解析存档的方法
16 *Culture 为 ECultureTeam 下的 EN、ZH等值,
17 * 四个参数分别对应Json中的 Culture、MusicVolume、SoundVolume、RecordData
18 */
19 void RecordDataJsonRead(FString& Culture, float& MusicVolume, float& SoundVolume, TArray<FString>& RecordDataList);
20
21 private:
22 //读取Json文件到字符串
23 bool LoadStringFromFile(const FString& FileName, const FString& RelaPath, FString& ResultString);
24
25 private:
26 //存档文件名
27 FString RecordDataFileName;
28 //相对路径
29 FString RelativePath;
30
31 };
D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Private\Data\SlAiJsonHandle.cpp
1 #include "Data/SlAiJsonHandle.h"
2 #include "Common/SlAiHelper.h"
3
4 SlAiJsonHandle::SlAiJsonHandle()
5 {
6 RecordDataFileName = FString("RecordData.json");
7 RelativePath = FString("Res/ConfigData/");
8 }
9
10 void SlAiJsonHandle::RecordDataJsonRead(FString& Culture, float& MusicVolume, float& SoundVolume, TArray<FString>& RecordDataList)
11 {
12 //保存读取到的所有 Json 数据
13 FString JsonValue;
14
15 //读取文件保存到 JsonValue
16 LoadStringFromFile(RecordDataFileName, RelativePath, JsonValue);
17
18 //这是一个二维数组,用来保存解析出来的数据
19 TArray<TSharedPtr<FJsonValue>> JsonParsed;
20
21 //将读取出来的数据通过一个Json读取的共享类TJsonReaderFactory 保存到JsonReader的引用
22 TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonValue);
23
24 //解析
25 if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
26 {
27 //从对应数组下标,获取对应类型,对应字段的数据
28 Culture = JsonParsed[0]->AsObject()->GetStringField(FString("Culture"));
29 MusicVolume = JsonParsed[1]->AsObject()->GetNumberField(FString("MusicVolume"));
30 SoundVolume = JsonParsed[2]->AsObject()->GetNumberField(FString("SoundVolume"));
31
32 //获取存档数据
33 TArray<TSharedPtr<FJsonValue>> RecordDataArray = JsonParsed[3]->AsObject()->GetArrayField(FString("RecordData"));
34 for (int i = 0; i < RecordDataArray.Num(); ++i)
35 {
36 FString RecordDataName = RecordDataArray[i]->AsObject()->GetStringField(FString::FromInt(i));
37 //保存到
38 RecordDataList.Add(RecordDataName);
39 }
40 }
41 else
42 {
43 SlAiHelper::Debug(FString("Deserialize Failed"));
44 }
45 }
46
47 bool SlAiJsonHandle::LoadStringFromFile(const FString& FileName, const FString& RelaPath, FString& ResultString)
48 {
49 if (!FileName.IsEmpty())
50 {
51 //获取绝对路径 (ProjectContentDir() 是原来的 GameContentDir(), 4.26版本后改名了)
52 FString AbsoPath = FPaths::ProjectContentDir() + RelaPath + FileName;
53
54 //判断文件是否存在
55 if (FPaths::FileExists(AbsoPath))
56 {
57 if (FFileHelper::LoadFileToString(ResultString, *AbsoPath))
58 {
59 return true;
60 }
61 else
62 {
63 //加载不成功
64 SlAiHelper::Debug(FString("Load Error!!") + AbsoPath);
65 return false;
66 }
67 }
68 else
69 {
70 //输出文件不存在
71 SlAiHelper::Debug(FString("File Not Exist!!") + AbsoPath);
72 }
73 }
74 return false;
75 }
然后菜单初始化是调用Json文件,将配置内容初始化
d:\ue4 project\ue26.2\courseproject\slaicourse\Source\SlAiCourse\Public\Data\SlAiDataHandle.h
1 #include "SlAiTypes.h"
2 #include "CoreMinimal.h"
3
4
5 class SLAICOURSE_API SlAiDataHandle
6 {
7 public:
8 SlAiDataHandle();
9
10 static void Initialize();
11
12 static TSharedPtr<SlAiDataHandle> Get();
13
14 //修改语言
15 void ChangeLocalizationCulture(ECultureTeam Culture);
16 //修改菜单音量大小
17 void ResetMenuVolume(float MusicVol, float SoundVol);
18
19 public:
20 /**
21 * 这里没有使用 GamePlay 框架的 GameInstance,变量直接写到C++类中除非你主动销毁,否则他会一直存在
22 */
23 //语言状态
24 ECultureTeam CurrentCulture;
25 //音乐状态
26 float MusicVolume;
27 //音效状态
28 float SoundVolume;
29 //存档数据
30 TArray<FString> RecordDataList;
31
32 private:
33 //创建单例
34 static TSharedRef<SlAiDataHandle> Create();
35
36 //根据enum类型获取字符串(该方法只能用于UENUM()反射后的枚举,普通枚举不能这样搞)
37 template<typename TEnum>
38 FString GetEnumValueAsString(const FString& Name, TEnum Value);
39
40 //根据字符串获取enum值(该方法只能用于UENUM()反射后的枚举,普通枚举不能这样搞)
41 template<typename TEnum>
42 TEnum GetEnumValueFromString(const FString& Name, FString Value);
43
44 //初始化存档数据
45 void InitRecordData();
46
47 private:
48 static TSharedPtr<SlAiDataHandle> DataInstance;
49 };
D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Private\Data\SlAiDataHandle.cpp
1 #include "Data/SlAiDataHandle.h"
2 #include "Internationalization/Internationalization.h"
3 #include "Data/SlAiSingleton.h"
4 #include "Data/SlAiJsonHandle.h"
5 #include "Common/SlAiHelper.h"
6
7 TSharedPtr<SlAiDataHandle> SlAiDataHandle::DataInstance = NULL;
8
9 SlAiDataHandle::SlAiDataHandle()
10 {
11 ////初始化中文
12 //CurrentCulture = ECultureTeam::ZH;
13 ////初始化音乐
14 //MusicVolume = 0.5f;
15 ////初始化音效
16 //SoundVolume = 0.5f;
17
18 //初始化存档数据
19 InitRecordData();
20 }
21
22 void SlAiDataHandle::Initialize()
23 {
24 if (!DataInstance.IsValid())
25 {
26 DataInstance = Create();
27 }
28 }
29
30 TSharedPtr<SlAiDataHandle> SlAiDataHandle::Get()
31 {
32 Initialize();
33 return DataInstance;
34 }
35
36 TSharedRef<SlAiDataHandle> SlAiDataHandle::Create()
37 {
38 /**
39 *MakeShareable 可以用来创建共享指针和共享引用
40 */
41 TSharedRef<SlAiDataHandle> DataRef = MakeShareable(new SlAiDataHandle());
42 return DataRef;
43 }
44
45 void SlAiDataHandle::ChangeLocalizationCulture(ECultureTeam Culture)
46 {
47 switch (Culture)
48 {
49 case ECultureTeam::EN:
50 FInternationalization::Get().SetCurrentCulture(TEXT("en"));
51 break;
52 case ECultureTeam::ZH:
53 FInternationalization::Get().SetCurrentCulture(TEXT("zh"));
54 break;
55 }
56 //赋值
57 CurrentCulture = Culture;
58 }
59
60 void SlAiDataHandle::ResetMenuVolume(float MusicVol, float SoundVol)
61 {
62 if (MusicVol > 0)
63 {
64 MusicVolume = MusicVol;
65 }
66 if (SoundVol > 0)
67 {
68 SoundVolume = SoundVol;
69 }
70 }
71
72 //根据枚举值返回字符串
73 template<typename TEnum>
74 FString SlAiDataHandle::GetEnumValueAsString(const FString& Name, TEnum Value)
75 {
76 //通过UE4的FindObject寻找所有ANY_PACKAGE反射到的Name,寻找到后实例化后返回
77 const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, *Name, ture);
78
79 if (!EnumPtr)
80 {
81 return FString("InValid");
82 }
83 return EnumPtr->GetEnumName((int32)Value);
84 }
85
86 //根据字符串返回枚举值
87 template<typename TEnum>
88 TEnum SlAiDataHandle::GetEnumValueFromString(const FString& Name, FString Value)
89 {
90 const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, *Name, true);
91
92 if (!EnumPtr)
93 {
94 return TEnum(0);
95 }
96 return (TEnum)EnumPtr->GetIndexByName(FName(*FString(Value)));
97 }
98
99 void SlAiDataHandle::InitRecordData()
100 {
101 //获取语言
102 FString Culture;
103 //使用单例读取存档数据
104 SlAiSingleton<SlAiJsonHandle>::Get()->RecordDataJsonRead(Culture, MusicVolume, SoundVolume, RecordDataList);
105
106 //初始化语言
107 ChangeLocalizationCulture(GetEnumValueFromString<ECultureTeam>(FString("ECultureTeam"), Culture));
108
109 //输出打印
110 SlAiHelper::Debug(Culture + FString("--") + FString::SanitizeFloat(MusicVolume) + FString("--") + FString::SanitizeFloat(SoundVolume), 20.f);
111
112 //输出打印 RecordDataList 使用迭代器循环读取RecordDataList
113 for (TArray<FString>::TIterator It(RecordDataList); It; It++)
114 {
115 SlAiHelper::Debug(*It, 20.f);
116 }
117 }
====================================================================================================================================