【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!"));
    	}
    

    image

    網絡讀取 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 );
    

    image

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 );
    

參考


免責聲明!

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



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