UE4純C++實現遊戲快捷欄之物品讀取

七星易發表於2024-04-23

我們在上一步驟中建立了快捷欄的UI介面,在這一部分我們主要從Json檔案中讀取物品的相關資訊,以便填充到快捷欄中。

  1.Types.h:新增物品型別、物品屬性結構體(成員變數及初始化函式)

UE4純C++實現遊戲快捷欄之物品讀取
 1 // 物品型別
 2 namespace EObjectType
 3 {
 4     enum Type
 5     {
 6         Normal = 0,    // 普通物品:木頭、石頭
 7         Food,        // 食物:蘋果、肉
 8         Tool,        // 工具:錘子、斧子
 9         Weapon        // 武器:劍
10     };
11 }
12 
13 // 物品屬性結構體
14 struct ObjectAttribute 
15 {
16     FText EN;    // 英文名
17     FText ZH;    // 中文名
18     EObjectType::Type ObjectType;    // 物品型別
19     int PlantAttack;    // 對植物的攻擊力
20     int MetalAttack;    // 對金屬資源的攻擊力
21     int AnimalAttack;    // 對動物的攻擊力
22     int AffectRange;    // 攻擊距離
23     FString TexPath;    // 圖片路徑
24 
25     // 建構函式
26     ObjectAttribute(const FText ENName, const FText ZHName, const EObjectType::Type OT, const int PA, const int MA,
27         const int AA, const int AR, const FString TP) : EN(ENName), ZH(ZHName), ObjectType(OT), PlantAttack(PA),
28         MetalAttack(MA), AnimalAttack(MA), AffectRange(AR), TexPath(TP)
29     {}
30 
31 };
View Code

  2.JsonHandle.h:新增物品解析(解析函式、檔名、路徑)、從string解析ObjectType

UE4純C++實現遊戲快捷欄之物品讀取
 1 {
 2 public:
 3     
 4 
 5     // 解析物品屬性
 6     void ObjectAttrJsonRead(TMap<int, TSharedPtr<ObjectAttribute>>& ObjectAttrMap);
 7 
 8 private:
 9 
10     
11     // 定義一個從 FString 轉換到 ObjectType 的方法
12     EObjectType::Type StringToObjectType(const FString ArgStr);
13 
14 private:
15 
16     FString RecordDataFileName;
17 
18     // 物品屬性檔名
19     FString ObjectAttrFileName;
20 
21     FString RelativePath;
22 };
View Code

  3.JsonHandle.cpp:建構函式中繫結Json檔案路徑、ObjectAttrJsonRead函式(讀取Json檔案並將物品列表根據id存在ObjectAttrMap中)、StringToObjectType函式解析string到ObjectType

UE4純C++實現遊戲快捷欄之物品讀取
 1 SlAiJsonHandle::SlAiJsonHandle()
 2 {
 3     RecordDataFileName = FString("RecordData.json");
 4     // 新增物品屬性的 Json 檔案路徑
 5     ObjectAttrFileName = FString("ObjectAttribute.json");
 6 
 7     RelativePath = FString("Res/ConfigData/");
 8 }
 9 
10 // 讀取物品的 Json 資訊
11 void SlAiJsonHandle::ObjectAttrJsonRead(TMap<int, TSharedPtr<ObjectAttribute>>& ObjectAttrMap)
12 {
13     FString JsonValue;
14     LoadStringFromFile(ObjectAttrFileName, RelativePath, JsonValue);
15 
16     TArray<TSharedPtr<FJsonValue>> JsonParsed;
17     TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonValue);
18 
19     if (FJsonSerializer::Deserialize(JsonReader, JsonParsed)) {
20         for (int i = 0; i < JsonParsed.Num(); ++i) {
21             TArray<TSharedPtr<FJsonValue>> ObjectAttr = JsonParsed[i]->AsObject()->GetArrayField(FString::FromInt(i));
22             FText EN = FText::FromString(ObjectAttr[0]->AsObject()->GetStringField("EN"));
23             FText ZH = FText::FromString(ObjectAttr[1]->AsObject()->GetStringField("ZH"));
24             FString ObjectTypeStr = ObjectAttr[2]->AsObject()->GetStringField("ObjectType");
25             int PlantAttack = ObjectAttr[3]->AsObject()->GetIntegerField("PlantAttack");
26             // 老師的變數名打錯了,如果像我這樣把 MetalAttcck 改成 MetalAttack 的話,Json 檔案
27             // 裡面的物件名記得改一下
28             int MetalAttack = ObjectAttr[4]->AsObject()->GetIntegerField("MetalAttack");
29             int AnimalAttack = ObjectAttr[5]->AsObject()->GetIntegerField("AnimalAttack");
30             int AffectRange = ObjectAttr[6]->AsObject()->GetIntegerField("AffectRange");
31             FString TexPath = ObjectAttr[7]->AsObject()->GetStringField("TexPath");
32             
33             EObjectType::Type ObjectType = StringToObjectType(ObjectTypeStr);
34             TSharedPtr<ObjectAttribute> ObjectAttrPtr = MakeShareable(new ObjectAttribute(EN, ZH, ObjectType, PlantAttack, MetalAttack, AnimalAttack, AffectRange, TexPath));
35             
36             ObjectAttrMap.Add(i, ObjectAttrPtr);
37         }
38     }
39     else {
40         SlAiHelper::Debug(FString("Deserialize Failed"));
41     }
42 }
43 
44 
45 // 這裡硬編碼是因為資料結構類裡面,這個列舉型別沒有新增反射宏,沒辦法用 SlAiDataHandle 裡的類似程式碼
46 // 如果讀者想寫得通用些的話參考 SlAiDataHandle 的類似程式碼
47 EObjectType::Type StringToObjectType(const FString ArgStr)
48 {
49     if (ArgStr.Equals(FString("Normal"))) return EObjectType::Normal;
50     if (ArgStr.Equals(FString("Food"))) return EObjectType::Food;
51     if (ArgStr.Equals(FString("Tool"))) return EObjectType::Tool;
52     if (ArgStr.Equals(FString("Weapon"))) return EObjectType::Weapon;
53     return EObjectType::Normal;
54 }
View Code

相關文章