虚幻引擎4中的C++嵌套JSON

Dav*_*vid 7 c++ json unreal-engine4

我有一个JSON对象,我从我的服务器,看起来像这样:

{
    "state":"1",
    "player1": {
        "alias":"Player Name",
        "ready":"0"
    }
}
Run Code Online (Sandbox Code Playgroud)

我能够获取JSON,将其解析为FJsonObject,并使用此代码序列化检索JSON对象的第一级中的任何数字或字符串:

TSharedPtr<FJsonObject> JsonParsed;
TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(json);
if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
    //Use JsonParsed
Run Code Online (Sandbox Code Playgroud)

这段代码读取字符串:

FString AJSONContainer::getStringWithKey(FString key)
{
    return storedJSON->GetStringField(key);
}    
Run Code Online (Sandbox Code Playgroud)

边注:

AJSONContainer只是一个Actor类,我用它来从Blueprints调用这些函数.


这一切都很好,但是当我尝试从二级读取东西时,事情就不起作用了.

我编写了这段代码来提升下一级别:

TSharedPtr<FJsonObject> nested = storedJSON->GetObjectField(key);
Run Code Online (Sandbox Code Playgroud)

但所有要求获得领域的电话nested都没有.

nested->GetStringField(anotherKey); //Nothing
Run Code Online (Sandbox Code Playgroud)

所以,例如,使用上面的JSON,这个:

TSharedPtr<FJsonObject> nested = storedJSON->GetObjectField("player1");
FString alias = nested->GetStringField("alias");
Run Code Online (Sandbox Code Playgroud)

alias 将它打印到控制台时没有任何价值.


难道我做错了什么?为什么二级JSON不起作用?

小智 10

不知道你是否解决了它,但我发现了一个非常讨厌的函数,适用于嵌套对象,也适用于数组.并且它为您提供了一个USTRUCT,因此您不必使用通过Keys获取值的函数(我不喜欢它们,因为它们非常容易出错).相反,你会有类型安全!

FJsonObjectConverter :: JsonObjectStringToUStruct

以下是UE4 AnswerHub上的文档和另一个问题

基本上,您创建目标USTRUCT(或嵌套JSON的USTRUCT),使用UPROPERTY标记所有属性,因此Unreal知道它们的名称,并使用此函数.它将通过匹配它们来复制值.它甚至复制阵列!= d

我将JSON FString称为反序列化的Json,它的结构如下所示.它包含一个嵌套对象和一个数组,以使事情变得有趣.

{
    "nested" : {
        "id" : "654asdf",
        "name" : "The Name"
    },
    "foo" : "foobar",
    "bar_arr" : [
        { "barfoo" : "asdf" },
        { "barfoo" : "qwer" }
    ]
}
Run Code Online (Sandbox Code Playgroud)

在转换之前,我们需要从里到外创建USTRUCT(因此我们可以在外部引用内部).请记住始终使用F作为结构名称.

USTRUCT()
struct FNested
{
    GENERATED_USTRUCT_BODY()

    UPROPERTY()
    FString id;

    UPROPERTY()
    FString name;
};

USTRUCT()
struct FBar
{
    GENERATED_USTRUCT_BODY()

    UPROPERTY()
    FString barfoo;
};

USTRUCT()
struct FJsonData
{
    GENERATED_USTRUCT_BODY()

    UPROPERTY()
    FNested nested;

    UPROPERTY()
    FString foo;

    UPROPERTY()
    TArray<FBar> bar_arr;
};
Run Code Online (Sandbox Code Playgroud)

转换将如下所示:

FJsonData JsonData;
FJsonObjectConverter::JsonObjectStringToUStruct<FJsonData>(
    Json,
    &JsonData,
    0, 0);
Run Code Online (Sandbox Code Playgroud)

现在,您可以像在标准C++结构中一样访问所有属性.例如,要访问其中一个barfoo:

FString barfoo0 = JsonData.bar_arr[0].barfoo;
Run Code Online (Sandbox Code Playgroud)

我没有使用int和float在JSON中测试它,但由于它复制了偶数数组,我相信它也可以工作.