UE4 從無到有純 C++ & Slate 開發沙盒游戲(十) 模板單例與文件讀取


這個部分將會寫一些數據方面的部分,前邊代碼中有過語言、音量等數據。這些數據是記錄到 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 }

 

 

 

 

 

 

 

 

 

 ==============================================================================================

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM