如何在Unreal C++中解析Pandas DataFrame输出的JSON格式字符串
UE4 解析Pandas输出的3D点JSON数据方案
前置依赖配置
首先打开项目的.Build.cs文件,在公共依赖模块中新增Json模块,示例如下:
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HTTP", // 你已有的HTTP模块 "Json" // 新增JSON解析模块 });
1. 修改HttpActor.h头文件
新增JSON相关头文件引用,可自定义3D点存储结构体方便后续使用:
#pragma once #include "GameFramework/Actor.h" #include "Runtime/Online/HTTP/Public/Http.h" #include "Dom/JsonObject.h" // 新增JSON对象头 #include "CoreMinimal.h" #include "HttpActor.generated.h" // 自定义3D标注点结构体,可选定义 USTRUCT(BlueprintType) struct F3DLabeledPoint { GENERATED_BODY() UPROPERTY(BlueprintReadWrite, Category = "3D Point") double X; UPROPERTY(BlueprintReadWrite, Category = "3D Point") double Y; UPROPERTY(BlueprintReadWrite, Category = "3D Point") double Z; UPROPERTY(BlueprintReadWrite, Category = "3D Point") int32 Label; UPROPERTY(BlueprintReadWrite, Category = "3D Point") FString PointId; }; UCLASS() class UE4CPPEXAMPLE_API AHttpActor : public AActor { GENERATED_BODY() public: AHttpActor(const class FObjectInitializer& ObjectInitializer); virtual void BeginPlay() override; FHttpModule* Http; void OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful); };
2. 修改HttpActor.cpp的OnResponseReceived实现
直接对应你给出的Python逻辑实现解析遍历:
#include "UE4CPPExample.h" #include "HttpActor.h" #include "Templates/SharedPointer.h" #include "Serialization/JsonReader.h" // 新增JSON读取头 #include "Serialization/JsonSerializer.h" // 新增JSON序列化头 // 原有构造函数、BeginPlay代码不变,仅修改OnResponseReceived void AHttpActor::OnResponseReceived( FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful ){ // 先判断请求是否成功、响应是否有效 if (!bWasSuccessful || !Response.IsValid() || Response->GetResponseCode() != 200) { GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Red, TEXT("请求失败")); return; } FString ResponseStr = Response->GetContentAsString(); // 解析JSON字符串,对应Python的json.loads TSharedPtr<FJsonObject> RootJsonObject; TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(ResponseStr); if (!FJsonSerializer::Deserialize(Reader, RootJsonObject) || !RootJsonObject.IsValid()) { GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Red, TEXT("JSON解析失败")); return; } // 分别取出x/y/z/label四个二级对象 TSharedPtr<FJsonObject> XObject = RootJsonObject->GetObjectField(TEXT("x")); TSharedPtr<FJsonObject> YObject = RootJsonObject->GetObjectField(TEXT("y")); TSharedPtr<FJsonObject> ZObject = RootJsonObject->GetObjectField(TEXT("z")); TSharedPtr<FJsonObject> LabelObject = RootJsonObject->GetObjectField(TEXT("label")); // 校验四个对象是否都存在 if (!XObject.IsValid() || !YObject.IsValid() || !ZObject.IsValid() || !LabelObject.IsValid()) { GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Red, TEXT("JSON格式不符合预期")); return; } // 遍历x的所有键,对应Python的for key in data_dictionary['x'].keys() TArray<FString> PointIds; XObject->Values.GetKeys(PointIds); for (const FString& PointId : PointIds) { // 取出对应字段的值 double X = XObject->GetNumberField(PointId); double Y = YObject->GetNumberField(PointId); double Z = ZObject->GetNumberField(PointId); int32 Label = LabelObject->GetIntegerField(PointId); // 输出到屏幕,对应Python的print FString PointInfo = FString::Printf(TEXT("点ID:%s | X:%.6f | Y:%.6f | Z:%.6f | 标签:%d"), *PointId, X, Y, Z, Label); GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, PointInfo); // 也可以存入结构体数组供后续使用 // F3DLabeledPoint NewPoint; // NewPoint.PointId = PointId; // NewPoint.X = X; // NewPoint.Y = Y; // NewPoint.Z = Z; // NewPoint.Label = Label; // PointArray.Add(NewPoint); } }
内容的提问来源于stack exchange,提问作者Bengt
相关产品推荐
相关产品推荐

