這個部分將會寫一些數據方面的部分,前邊代碼中有過語言、音量等數據。這些數據是記錄到 json 文件中的。
如:D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Content\Res\ConfigDate\RecordData.json
[ { "Culture":"ZH" }, { "MusicVolume": 0.3 }, { "SoundVolume": 0.3 }, { "RecordData": [ { "0": "Default" } ] } ]
UE4項目讀取 json 文件,需在項目的 Build 文件添加相關 Module ,如:
D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\SlAiCourse.Build.cs
1 // Copyright Epic Games, Inc. All Rights Reserved. 2 3 using UnrealBuildTool; 4 5 public class SlAiCourse : ModuleRules 6 { 7 public SlAiCourse(ReadOnlyTargetRules Target) : base(Target) 8 { 9 PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 11 PublicDependencyModuleNames.AddRange(new string[] 12 { 13 "Core", 14 "CoreUObject", 15 "Engine", 16 "InputCore", 17 "Slate", //由於要使用 Slate 的UI架構,這里加 Slate 的 Module 18 "SlateCore", 19 "Json", 20 "JsonUtilities", //Json 工具 21 }); 22 23 PrivateDependencyModuleNames.AddRange(new string[] { }); 24 25 // Uncomment if you are using Slate UI 26 // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); 27 28 // Uncomment if you are using online features 29 // PrivateDependencyModuleNames.Add("OnlineSubsystem"); 30 31 // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true 32 } 33 }
添加完后一定要運行編譯一次項目,讓項目添加下Module,避免直接使用出現一些莫名其妙的報錯
新建兩個C++類
要在 SlAiSingleton類中實現C++基於模板類的單例模式,和一個JsonHandle的控制類
然后去 SlAiDataHandle 添加兩個模板方法
1. 根據enum類型獲取字符串
2. 根據字符串獲取enum值
下方代碼中加粗的內容
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 private: 31 //創建單例 32 static TSharedRef<SlAiDataHandle> Create(); 33 34 //根據enum類型獲取字符串(該方法只能用於UENUM()反射后的枚舉,普通枚舉不能這樣搞) 35 template<typename TEnum> 36 FString GetEnumValueAsString(const FString& Name, TEnum Value); 37 38 //根據字符串獲取enum值(該方法只能用於UENUM()反射后的枚舉,普通枚舉不能這樣搞) 39 template<typename TEnum> 40 TEnum GetEnumValueFromString(const FString& Name, FString Value); 41 42 private: 43 static TSharedPtr<SlAiDataHandle> DataInstance; 44 45 };
相關實現
D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Private\Data\SlAiDataHandle.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "Data/SlAiDataHandle.h" #include "Internationalization/Internationalization.h" TSharedPtr<SlAiDataHandle> SlAiDataHandle::DataInstance = NULL; SlAiDataHandle::SlAiDataHandle() { //初始化中文 CurrentCulture = ECultureTeam::ZH; //初始化音樂 MusicVolume = 0.5f; //初始化音效 SoundVolume = 0.5f; } void SlAiDataHandle::Initialize() { if (!DataInstance.IsValid()) { DataInstance = Create(); } } TSharedPtr<SlAiDataHandle> SlAiDataHandle::Get() { Initialize(); return DataInstance; } TSharedRef<SlAiDataHandle> SlAiDataHandle::Create() { /** *MakeShareable 可以用來創建共享指針和共享引用 */ TSharedRef<SlAiDataHandle> DataRef = MakeShareable(new SlAiDataHandle()); return DataRef; } void SlAiDataHandle::ChangeLocalizationCulture(ECultureTeam Culture) { switch (Culture) { case ECultureTeam::EN: FInternationalization::Get().SetCurrentCulture(TEXT("en")); break; case ECultureTeam::ZH: FInternationalization::Get().SetCurrentCulture(TEXT("zh")); break; } //賦值 CurrentCulture = Culture; } void SlAiDataHandle::ResetMenuVolume(float MusicVol, float SoundVol) { if (MusicVol > 0) { MusicVolume = MusicVol; } if (SoundVol > 0) { SoundVolume = SoundVol; } } template<typename TEnum> FString SlAiDataHandle::GetEnumValueAsString(const FString& Name, TEnum Value) { //通過UE4的FindObject尋找所有ANY_PACKAGE反射到的Name,尋找到后實例化后返回 const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, *Name, ture); if (!EnumPtr) { return FString("InValid"); } return EnumPtr->GetEnumName((int32)Value); } template<typename TEnum> TEnum SlAiDataHandle::GetEnumValueFromString(const FString& Name, FString Value) { const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, *Name, ture); if (!EnumPtr) { return TEnum(0); } return (TEnum)EnumPtr->GetIndexByName(FName(*FString(Value))); }
寫一個基於模板的單例 SlAiSingleton ,算是一個擴展
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 static void Initialize(); 14 15 static TSharedPtr<T> Cteate(); 16 17 private: 18 static TSharedPtr<T> TInstance; 19 };
d:\ue4 project\ue26.2\courseproject\slaicourse\Source\SlAiCourse\Private\Data\SlAiSingleton.cpp
1 #include "Data/SlAiSingleton.h" 2 3 template<class T> 4 TSharedPtr<T> SlAiSingleton<T>::TInstance = NULL; 5 6 //創建一個共享的引用 7 template<class T> 8 TSharedPtr<T> SlAiSingleton<T>::Cteate() 9 { 10 TSharedPtr<T> TRef = MakeShareable(new T()); 11 return TRef; 12 } 13 14 template<class T> 15 void SlAiSingleton<T>::Initialize() 16 { 17 //判斷指針是否存在,如果不存在則Cteate一個 18 if (!TInstance->IsValid()) 19 { 20 TInstance = Cteate(); 21 } 22 } 23 24 template<class T> 25 TSharedPtr<T> SlAiSingleton<T>::Get() 26 { 27 Initialize(); 28 return TInstance; 29 }
然后實現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 private: 15 //讀取Json文件到字符串 16 bool LoadStringFromFile(const FString& FileName, const FString& RelaPath, FString& ResultString); 17 18 private: 19 //存檔文件名 20 FString RecordDataFileName; 21 //相對路徑 22 FString RelativePath; 23 24 };
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 bool SlAiJsonHandle::LoadStringFromFile(const FString& FileName, const FString& RelaPath, FString& ResultString) 11 { 12 if (!FileName.IsEmpty()) 13 { 14 //獲取絕對路徑 15 FString AbsoPath = FPaths::GameContentDir() + RelaPath + FileName; 16 17 //判斷文件是否存在 18 if (FPaths::FileExists(AbsoPath)) 19 { 20 if (FFileHelper::LoadFileToString(ResultString, *AbsoPath)) 21 { 22 return true; 23 } 24 else 25 { 26 //加載不成功 27 SlAiHelper::Debug(FString("Load Error!!") + AbsoPath); 28 } 29 } 30 else 31 { 32 //輸出文件不存在 33 SlAiHelper::Debug(FString("File Not Exist!!") + AbsoPath); 34 } 35 } 36 37 return false; 38 }
==============================================================================================