【UE4 C++】 解析与构建 Json 数据
准备条件
Json 格式
{
"Players":[
{
"Name": "Player1",
"health": 200,
"icon": "Texture2D'/Game/FourEvilDragonsHP/Textures/DragonTheUsurper/BlueHPTex.BlueHPTex'"
},
{
"Name": "Player2",
"health": 90,
"icon": "Texture2D'/Game/FourEvilDragonsHP/Textures/DragonTheSoulEater/BlueHPTex.BlueHPTex'"
},
{
"Name": "Player3",
"health": 150,
"icon": "None"
}
]
}
UE4 添加Json模块
Build.cs中将Json模块导入
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG", "Json" });
数据说明
FJsonObject
-
表示一个Json对象,可以作为值 嵌套
-
读取数据相关节点
TSharedPtr<FJsonValue> TryGetField( const FString& FieldName ) bool HasField( const FString& FieldName) double GetNumberField(const FString& FieldName) int32 GetIntegerField(const FString& FieldName) bool TryGetNumberField(const FString& FieldName, double& OutNumber) bool TryGetNumberField(const FString& FieldName, int32& OutNumber) bool TryGetNumberField(const FString& FieldName, uint32& OutNumber) bool TryGetNumberField(const FString& FieldName, int64& OutNumber) FString GetStringField(const FString& FieldName) bool TryGetStringField(const FString& FieldName, FString& OutString) bool TryGetStringArrayField(const FString& FieldName, TArray<FString>& OutArray) bool TryGetEnumArrayField(const FString& FieldName, TArray<TEnum>& OutArray) bool GetBoolField(const FString& FieldName) bool TryGetBoolField(const FString& FieldName, bool& OutBool) const TArray< TSharedPtr<FJsonValue> >& GetArrayField(const FString& FieldName) bool TryGetArrayField(const FString& FieldName, const TArray< TSharedPtr<FJsonValue> >*& OutArray) const TSharedPtr<FJsonObject>& GetObjectField(const FString& FieldName) bool TryGetObjectField(const FString& FieldName, const TSharedPtr<FJsonObject>*& OutObject)
-
存储数据的节点
void SetField( const FString& FieldName, const TSharedPtr<FJsonValue>& Value ) void RemoveField(const FString& FieldName); void SetNumberField( const FString& FieldName, double Number ) void SetStringField( const FString& FieldName, const FString& StringValue ) void SetBoolField( const FString& FieldName, bool InValue ) void SetArrayField( const FString& FieldName, const TArray< TSharedPtr<FJsonValue> >& Array ) void SetObjectField( const FString& FieldName, const TSharedPtr<FJsonObject>& JsonObject )
FJsonValue
读取 Json 数据
本地读取
-
注意 JsonReader 的类型
TSharedRef<TJsonReader<>>
,使用TJsonReaderFactory<>::Create
创建 -
使用 FJsonSerializer::Deserialize 将 Json String 转成 JsonObject
-
FJsonValue 可以再度转化城成FJsonObject,或者直接提取 基本类型数据
FString JsonPath = FPaths::ProjectDir() + TEXT("DataDrive/UserInfo.json"); JsonPath = FPaths::ConvertRelativePathToFull(JsonPath); if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*JsonPath)) { UKismetSystemLibrary::PrintString(GetWorld(), *JsonPath); FString JsonData; FFileHelper::LoadFileToString(JsonData, *JsonPath); // FString 转 JsonObj TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(JsonData); TSharedPtr<FJsonObject> RootJsonObj = MakeShareable(new FJsonObject); if (FJsonSerializer::Deserialize(JsonReader, RootJsonObj)) { UE_LOG(LogTemp, Warning, TEXT("JsonData:%s"), *JsonData ); const TArray< TSharedPtr<FJsonValue> >* members; if (RootJsonObj->TryGetArrayField(TEXT("Players"),members)) { for (TSharedPtr<FJsonValue> item: * members) { TSharedPtr<FJsonObject>itemObjet = item->AsObject(); UE_LOG(LogTemp, Warning, TEXT("name:%s health:%d"), *itemObjet->GetStringField(TEXT("Name")),itemObjet->GetIntegerField(TEXT("health")) ); } } } else UKismetSystemLibrary::PrintString(GetWorld(), TEXT("FJsonSerializer::Deserialize Failed!")); }
网络读取 Json
- 与本地类似,但是通过 URL 获取 Json 数据
- 可以使用 VaRest 插件,支持读写
写入 Json 数据
基本类型构造 Json 数据
-
注意 Write 类型为 TSharedRef<TJsonWriter<>>,使用
TJsonWriterFactory<>::Create()
创建 -
步骤
- WriteObjectStart
- WriteValue 普通字段
- 数组字段
- WriteArrayStart
- WriteObjectStart
- WriteValue (可以多个字段)
- WriteObjectEnd
- WriteArrayEnd
- WriteObjectEnd
- Close();
-
代码实现
struct Info { FString name; int32 health; }; FString InfoCategory = "Player State"; TArray<Info> Players; struct Info info; info.name = TEXT("城主"); info.health = 30; Players.Add(info); info.name = TEXT("白月魁"); info.health = 200; Players.Add(info); info.name = TEXT("临渊者"); info.health = 999; Players.Add(info); FString OutJsonData; TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutJsonData); //TSharedRef<TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>> Writer = TJsonWriterFactory< TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&OutJsonData); Writer->WriteObjectStart(); // JSON对象开始 Writer->WriteValue(L"category", InfoCategory); // 填充普通字段 Writer->WriteArrayStart(L"players"); // Json 数组字段开始 for (Info player : Players) { Writer->WriteObjectStart(); Writer->WriteValue(L"name", player.name); // 填充普通字段 Writer->WriteValue(L"health", player.health); // 填充普通字段 Writer->WriteObjectEnd(); } Writer->WriteArrayEnd(); // Json 数组字段结束 Writer->WriteObjectEnd(); //JSON对象结束 Writer->Close(); UE_LOG(LogTemp, Warning, TEXT("JsonData:%s"), *OutJsonData );
FJsonObject 构造 Json 数据
-
主要 FJsonObject 转 JsonValue
-
FJsonSerializer::Serialize 将 FJsonObject 转 FString
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject); TArray<TSharedPtr<FJsonValue>> PlayersData; TSharedPtr<FJsonObject> Player1 = MakeShareable(new FJsonObject); Player1->SetStringField(TEXT("name"), TEXT("城主")); Player1->SetNumberField(TEXT("health"), 30); Player1->SetStringField(TEXT("icon"), TEXT("")); PlayersData.Add(MakeShareable(new FJsonValueObject(Player1))); TSharedPtr<FJsonObject> Player2 = MakeShareable(new FJsonObject); Player2->SetStringField(TEXT("name"), TEXT("白月魁")); Player2->SetNumberField(TEXT("health"), 200); Player2->SetStringField(TEXT("icon"), TEXT("")); PlayersData.Add(MakeShareable(new FJsonValueObject(Player2))); TSharedPtr<FJsonObject> Player3 = MakeShareable(new FJsonObject); Player3->SetStringField(TEXT("name"), TEXT("临渊者")); Player3->SetNumberField(TEXT("health"), 999); Player3->SetStringField(TEXT("icon"), TEXT("")); PlayersData.Add(MakeShareable(new FJsonValueObject(Player3))); JsonObject->SetArrayField(TEXT("players"), PlayersData); FString OutJsonData; TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutJsonData); FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); UE_LOG(LogTemp, Warning, TEXT("JsonData:%s"), *OutJsonData );
参考
作者:砥才人
出处:https://www.cnblogs.com/shiroe
本系列文章为笔者整理原创,只发表在博客园上,欢迎分享本文链接,如需转载,请注明出处!