• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

UE4 从无到有纯 C++ & Slate 开发沙盒游戏(十二) 写入存档Json文件 ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

上一部分写的是Json文件的读取,并将读取到的内容初始化到设置界面对应的配置项上,而游戏中改变设置配置则无法保存到Json文件中,这一部分将会实现Json文件的配置写入。

 首先要先实现两个方法

1. 将JSon转换为Json格式字符串的方法

2. 保存字符串到文件的方法

 

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     //FJsonObject转换为Json格式的字符串
26     bool GetFStringInJSonData(const TSharedPtr<FJsonObject>& JsonObj, FString& JsonStr);
27 
28     //保存字符串到文件
29     bool WriteFileWithJsonData(const FString& JsonStr, const FString& RelaPath, const FString& FileName);
30 
31 private:
32     //存档文件名
33     FString RecordDataFileName;
34     //相对路径
35     FString RelativePath;
36 
37 };

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 }
 76 
 77 bool SlAiJsonHandle::GetFStringInJSonData(const TSharedPtr<FJsonObject>& JsonObj, FString& JsonStr)
 78 {
 79     if (JsonObj.IsValid() && JsonObj->Values.Num() > 0)
 80     {
 81         TSharedRef<TJsonWriter<TCHAR>> JsonWriter = TJsonWriterFactory<TCHAR>::Create(&JsonStr);
 82         FJsonSerializer::Serialize(JsonObj.ToSharedRef(), JsonWriter);
 83         return true;
 84     }
 85     return false;
 86 }
 87 
 88 bool SlAiJsonHandle::WriteFileWithJsonData(const FString& JsonStr, const FString& RelaPath, const FString& FileName)
 89 {
 90     if (!JsonStr.IsEmpty())    //判断字符串是否为空
 91     {
 92         if (!FileName.IsEmpty())
 93         {
 94             FString AbsoPath = FPaths::ProjectContentDir() + RelaPath + FileName;
 95             //保存
 96             if (FFileHelper::SaveStringToFile(JsonStr, *AbsoPath))
 97             {
 98                 return true;
 99             }
100             else
101             {
102                 SlAiHelper::Debug(FString("Save") + AbsoPath + FString("-->Failed"), 30.f);
103             }
104         }
105         SlAiHelper::Debug(FString("!FileName.IsEmpty() ==False"), 30.f);
106     }
107     SlAiHelper::Debug(FString("!JsonStr.IsEmpty() ==False"), 30.f);
108 }

 

然后开始写更新数据,需要在 SlAiDataHandle 中调用 SlAiJsonHandle 的方法

先转换成JsonObject,然后转成Json,然后存入到存档文件

再在 SlAiDataHandle 文件中添加一个修改存档的 public 方法 UpdateRecordData,这个方法没写返回值,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     //修改存档
22     void UpdateRecordData(FString Culture, float MusicVolume, float SoundVolume, TArray<FString>* RecordDataList);
23 
24 private:
25     //读取Json文件到字符串
26     bool LoadStringFromFile(const FString& FileName, const FString& RelaPath, FString& ResultString);
27 
28     //FJsonObject转换为Json格式的字符串
29     bool GetFStringInJSonData(const TSharedPtr<FJsonObject>& JsonObj, FString& JsonStr);
30 
31     //保存字符串到文件
32     bool WriteFileWithJsonData(const FString& JsonStr, const FString& RelaPath, const FString& FileName);
33 
34 private:
35     //存档文件名
36     FString RecordDataFileName;
37     //相对路径
38     FString RelativePath;
39 
40 };

 

UpdateRecordData 实现

D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Private\Data\SlAiJsonHandle.cpp

  1 // Fill out your copyright notice in the Description page of Project Settings.
  2 
  3 #include "Data/SlAiJsonHandle.h"
  4 #include "Common/SlAiHelper.h"
  5 
  6 SlAiJsonHandle::SlAiJsonHandle()
  7 {
  8     RecordDataFileName = FString("RecordData.json");
  9     RelativePath = FString("Res/ConfigData/");
 10 }
 11 
 12 void SlAiJsonHandle::RecordDataJsonRead(FString& Culture, float& MusicVolume, float& SoundVolume, TArray<FString>& RecordDataList)
 13 {
 14     //保存读取到的所有 Json 数据
 15     FString JsonValue;
 16 
 17     //读取文件保存到 JsonValue
 18     LoadStringFromFile(RecordDataFileName, RelativePath, JsonValue);
 19 
 20     //这是一个二维数组,用来保存解析出来的数据
 21     TArray<TSharedPtr<FJsonValue>> JsonParsed;
 22 
 23     //将读取出来的数据通过一个Json读取的共享类TJsonReaderFactory 保存到JsonReader的引用
 24     TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonValue);
 25 
 26     //解析
 27     if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
 28     {
 29         //从对应数组下标,获取对应类型,对应字段的数据
 30         Culture = JsonParsed[0]->AsObject()->GetStringField(FString("Culture"));
 31         MusicVolume = JsonParsed[1]->AsObject()->GetNumberField(FString("MusicVolume"));
 32         SoundVolume = JsonParsed[2]->AsObject()->GetNumberField(FString("SoundVolume"));
 33 
 34         //获取存档数据
 35         TArray<TSharedPtr<FJsonValue>> RecordDataArray = JsonParsed[3]->AsObject()->GetArrayField(FString("RecordData"));
 36         for (int i = 0; i < RecordDataArray.Num(); ++i)
 37         {
 38             FString RecordDataName = RecordDataArray[i]->AsObject()->GetStringField(FString::FromInt(i));
 39             //保存到
 40             RecordDataList.Add(RecordDataName);
 41         }
 42     }
 43     else
 44     {
 45         SlAiHelper::Debug(FString("Deserialize Failed"));
 46     }
 47 }
 48 
 49 void SlAiJsonHandle::UpdateRecordData(FString Culture, float MusicVolume, float SoundVolume, TArray<FString>* RecordDataList)
 50 {
 51     TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
 52 
 53     //文件最外围是个数组
 54     TArray<TSharedPtr<FJsonValue>> BaseDataArray;
 55     /*
 56     * 实例化一个FJsonObject;通过 SetStringField 传入的 Key 输入对应的参数;将 CultureValue 传入BaseDataArray 需要先将 FJsonObject 类型转换为 FJsonValue
 57     */ 
 58     TSharedPtr<FJsonObject> CultureObject = MakeShareable(new FJsonObject);
 59     CultureObject->SetStringField("Culture", Culture);
 60     TSharedPtr<FJsonValueObject> CultureValue = MakeShareable(new FJsonValueObject(CultureObject));
 61 
 62     TSharedPtr<FJsonObject> MusicVolumeObject = MakeShareable(new FJsonObject);
 63     MusicVolumeObject->SetNumberField("MusicVolume", MusicVolume);
 64     TSharedPtr<FJsonValueObject> MusicVolumeValue = MakeShareable(new FJsonValueObject(MusicVolumeObject));
 65 
 66     TSharedPtr<FJsonObject> SoundVolumeObject = MakeShareable(new FJsonObject);
 67     SoundVolumeObject->SetNumberField("SoundVolume", SoundVolume);
 68     TSharedPtr<FJsonValueObject> SoundVolumeValue = MakeShareable(new FJsonValueObject(SoundVolumeObject));
 69 
 70     //最后一部分还是数组,这里通过一个for循环将字符串转换为Json格式
 71     TArray<TSharedPtr<FJsonValue>> RecordDataArray;
 72     for (int i = 0; i < RecordDataList->Num(); i++)
 73     {
 74         TSharedPtr<FJsonObject> RecordItem = MakeShareable(new FJsonObject);
 75         RecordItem->SetStringField(FString::FromInt(i), (*RecordDataList)[i]);
 76         TSharedPtr<FJsonValueObject> RecordDataValue = MakeShareable(new FJsonValueObject(RecordItem));
 77         RecordDataArray.Add(RecordDataValue);
 78     }
 79     //将数组Json转成Value数据
 80     TSharedPtr<FJsonObject> RecordDataObject = MakeShareable(new FJsonObject);
 81     RecordDataObject->SetArrayField("RecordData", RecordDataArray);
 82     TSharedPtr<FJsonValueObject> RecordDataValue = MakeShareable(new FJsonValueObject(RecordDataObject));
 83 
 84     //加到最大的数组
 85     BaseDataArray.Add(CultureValue);
 86     BaseDataArray.Add(MusicVolumeValue);
 87     BaseDataArray.Add(SoundVolumeValue);
 88     BaseDataArray.Add(RecordDataValue);
 89     
 90     //把数组转换成JsonObject
 91     JsonObject->SetArrayField("T", BaseDataArray);
 92 
 93     //JsonObject转换为字符串
 94     FString JsonStr;
 95     GetFStringInJSonData(JsonObject, JsonStr);
 96 
 97     SlAiHelper::Debug(FString("Origin Str:" + JsonStr), 60.F);
 98 
 99     //去掉多余字符
100     JsonStr.RemoveAt(0, 8);
101     JsonStr.RemoveFromEnd(FString("}"));
102 
103     SlAiHelper::Debug(FString("Final Str:" + JsonStr), 60.F);
104 
105     //写入文件
106     WriteFileWithJsonData(JsonStr, RelativePath, RecordDataFileName);
107 }
108 
109 bool SlAiJsonHandle::LoadStringFromFile(const FString& FileName, const FString& RelaPath, FString& ResultString)
110 {
111     if (!FileName.IsEmpty())
112     {
113         //获取绝对路径 (ProjectContentDir() 是原来的 GameContentDir(), 4.26版本后改名了)
114         FString AbsoPath = FPaths::ProjectContentDir() + RelaPath + FileName;
115 
116         //判断文件是否存在
117         if (FPaths::FileExists(AbsoPath))
118         {
119             if (FFileHelper::LoadFileToString(ResultString, *AbsoPath))
120             {
121                 return true;
122             }
123             else
124             {
125                 //加载不成功
126                 SlAiHelper::Debug(FString("Load Error!!") + AbsoPath);
127                 return false;
128             }
129         }
130         else
131         {
132             //输出文件不存在
133             SlAiHelper::Debug(FString("File Not Exist!!") + AbsoPath);
134         }
135     }
136     return false;
137 }
138 
139 bool SlAiJsonHandle::GetFStringInJSonData(const TSharedPtr<FJsonObject>& JsonObj, FString& JsonStr)
140 {
141     if (JsonObj.IsValid() && JsonObj->Values.Num() > 0)
142     {
143         TSharedRef<TJsonWriter<TCHAR>> JsonWriter = TJsonWriterFactory<TCHAR>::Create(&JsonStr);
144         FJsonSerializer::Serialize(JsonObj.ToSharedRef(), JsonWriter);
145         return true;
146     }
147     return false;
148 }
149 
150 bool SlAiJsonHandle::WriteFileWithJsonData(const FString& JsonStr, const FString& RelaPath, const FString& FileName)
151 {
152     if (!JsonStr.IsEmpty())    //判断字符串是否为空
153     {
154         if (!FileName.IsEmpty())
155         {
156             FString AbsoPath = FPaths::ProjectContentDir() + RelaPath + FileName;
157             //保存
158             if (FFileHelper::SaveStringToFile(JsonStr, *AbsoPath))
159             {
160                 return true;
161             }
162             else
163             {
164                 SlAiHelper::Debug(FString("Save") + AbsoPath + FString("-->Failed"), 30.f);
165                 return false;
166             }
167         }
168         SlAiHelper::Debug(FString("!FileName.IsEmpty() ==False"), 30.f);
169         return false;
170     }
171     SlAiHelper::Debug(FString("!JsonStr.IsEmpty() ==False"), 30.f);
172     return false;
173 }

 

 

写入的相关方法写完了,然后游戏中在改变语言和声音配置时调用该方法

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     //
                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++MD5类封装发布时间:2022-07-13
下一篇:
tomcat启动提示java.lang.UnsatisfiedLinkError:D:\soft\devTool\apache-tomcat-7.0.5 ...发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap