上一篇隻是将一個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 }
====================================================================================================================================