UE4 中加载 JSON 文件的完整指南**
在 Unreal Engine (UE4) 开发中,JSON (JavaScript Object Notation) 文件因其轻量级、易读易写的特性,常被用于配置数据、存储游戏状态、传输信息等场景,如何在 UE4 中加载和解析 JSON 文件是开发者必备的技能,本文将详细介绍几种在 UE4 中加载 JSON 文件的常用方法,并提供代码示例。
使用 UE4 内置的 JsonObject 和 JsonReader (传统方式)
UE4 提供了内置的 JSON 处理类,主要位于 Serialization 模块中,这种方式不依赖第三方库,适合处理简单的 JSON 数据。
包含必要的头文件
在需要加载 JSON 的 C++ 文件中,包含以下头文件:
#include "Serialization/JsonReader.h" #include "Serialization/JsonSerializer.h" #include "JsonObject.h" // 需要包含这个来操作 JSON 对象 #include "Misc/FileHelper.h" #include "Paths.h"
加载并解析 JSON 文件的步骤
步骤 1:读取 JSON 文件内容到字符串
使用 FFileHelper::FileToString 函数将 JSON 文件的内容读取到一个 FString 中。
FString JsonContent;
const FString FilePath = FPaths::ProjectDir() + "Config/MyData.json"; // 假设 JSON 文件在 Config 目录下
if (!FFileHelper::FileToString(JsonContent, *FilePath))
{
UE_LOG(LogTemp, Error, TEXT("Failed to load JSON file from: %s"), *FilePath);
return; // 或返回错误
}
步骤 2:创建 JSON 读取器和 JSON 对象
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject); TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonContent);
步骤 3:解析 JSON 字符串
使用 JsonSerializer::Deserialize 函数将 JSON 字符串解析为 FJsonObject。
if (FJsonSerializer::Deserialize(JsonReader, JsonObject) && JsonObject.IsValid())
{
// 解析成功,可以开始读取数据
UE_LOG(LogTemp, Log, TEXT("JSON file parsed successfully!"));
// 示例:读取一个字符串值
FString stringValue;
if (JsonObject->TryGetStringField("playerName", stringValue))
{
UE_LOG(LogTemp, Log, TEXT("Player Name: %s"), *stringValue);
}
// 示例:读取一个数值
int32 playerLevel;
if (JsonObject->TryGetNumberField("playerLevel", playerLevel))
{
UE_LOG(LogTemp, Log, TEXT("Player Level: %d"), playerLevel);
}
// 示例:读取一个布尔值
bool isAlive;
if (JsonObject->TryGetBoolField("isAlive", isAlive))
{
UE_LOG(LogTemp, Log, TEXT("Is Alive: %s"), isAlive ? TEXT("true") : TEXT("false"));
}
// 示例:读取一个 JSON 数组
TArray<TSharedPtr<FJsonValue>> jsonArray;
if (JsonObject->TryGetArrayField("inventoryItems", jsonArray))
{
UE_LOG(LogTemp, Log, TEXT("Inventory Items:"));
for (const auto& Item : jsonArray)
{
if (Item->Type == EJson::String)
{
UE_LOG(LogTemp, Log, TEXT(" - %s"), *Item->AsString());
}
}
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to parse JSON content."));
}
JSON 文件示例 (MyData.json):
{
"playerName": "Alice",
"playerLevel": 10,
"isAlive": true,
"inventoryItems": ["Sword", "Shield", "Potion"]
}
使用 DataAsset 和 Blueprint 可读 JSON (蓝图友好方式)
对于希望直接在蓝图中访问 JSON 数据,或者希望将 JSON 数据作为资源管理的场景,可以创建一个自定义的 DataAsset 子类,并利用 UE4 的 BlueprintReadWrite 和 BlueprintPure 宏。
创建 C++ DataAsset 类
// MyJsonDataAsset.h
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataTable.h"
#include "MyJsonDataAsset.generated.h"
UCLASS(Blueprintable, BlueprintType)
class YOURPROJECT_API UMyJsonDataAsset : public UDataAsset
{
GENERATED_BODY()
public:
// 加载 JSON 文件并解析数据
UFUNCTION(BlueprintCallable, Category = "JSON|DataAsset")
bool LoadJsonFromFile(const FString& FilePath);
// 暴露给蓝图的解析后数据
UPROPERTY(BlueprintReadOnly, Category = "JSON|DataAsset")
FString PlayerName;
UPROPERTY(BlueprintReadOnly, Category = "JSON|DataAsset")
int32 PlayerLevel;
UPROPERTY(BlueprintReadOnly, Category = "JSON|DataAsset")
bool IsAlive;
UPROPERTY(BlueprintReadOnly, Category = "JSON|DataAsset")
TArray<FString> InventoryItems;
};
// MyJsonDataAsset.cpp
#include "MyJsonDataAsset.h"
#include "Serialization/JsonReader.h"
#include "Serialization/JsonSerializer.h"
#include "JsonObject.h"
#include "Misc/FileHelper.h"
bool UMyJsonDataAsset::LoadJsonFromFile(const FString& FilePath)
{
FString JsonContent;
if (!FFileHelper::FileToString(JsonContent, *FilePath))
{
UE_LOG(LogTemp, Error, TEXT("Failed to load JSON file from: %s"), *FilePath);
return false;
}
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonContent);
if (FJsonSerializer::Deserialize(JsonReader, JsonObject) && JsonObject.IsValid())
{
JsonObject->TryGetStringField("playerName", PlayerName);
JsonObject->TryGetNumberField("playerLevel", PlayerLevel);
JsonObject->TryGetBoolField("isAlive", IsAlive);
TArray<TSharedPtr<FJsonValue>> TempArray;
if (JsonObject->TryGetArrayField("inventoryItems", TempArray))
{
InventoryItems.Empty();
for (const auto& Item : TempArray)
{
if (Item->Type == EJson::String)
{
InventoryItems.Add(Item->AsString());
}
}
}
return true;
}
return false;
}
在蓝图中使用
- 创建一个
MyJsonDataAsset资源。 - 在蓝图中,调用
LoadJsonFromFile函数,传入 JSON 文件的路径。 - 加载成功后,即可直接访问
PlayerName,PlayerLevel等 exposed 属性。
使用第三方库 (如 RapidJSON)
对于更复杂的 JSON 处理或追求更高性能的场景,可以考虑使用第三方 JSON 库,如 RapidJSON,这需要先将库集成到 UE4 项目中。
集成步骤简述:
- 下载 RapidJSON。
- 将 RapidJSON 的头文件复制到 UE4 项目的
Source/YourProject/Public或一个公共的ThirdParty目录。 - 在项目的
Build.cs文件中添加对 RapidJSON 头文件路径的引用。
使用示例 (概念性):
#include "ThirdParty/RapidJSON/include/rapidjson/document.h"
#include "ThirdParty/RapidJSON/include/rapidjson/filewritestream.h"
#include "ThirdParty/RapidJSON/include/rapidjson/prettywriter.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
void LoadJsonWithRapidJSON()
{
FString JsonContent;
const FString FilePath = FPaths::ProjectDir() + "Config/MyData.json";
if (!FFileHelper::FileToString(JsonContent, *FilePath))
{
UE_LOG(LogTemp, Error, TEXT("Failed to load JSON file with RapidJSON."));
return;
}
rapidjson::Document Doc;
Doc.Parse<rapidjson::kParseDefaultFlags>(TCHAR_TO_UTF8(*JsonContent));
if (Doc.HasParseError())
{
UE_LOG(LogTemp, Error, TEXT("RapidJSON parse error: %s"), UTF8_TO_TCHAR(Doc.GetParseError()));
return;
}
if (Doc.IsObject())
{
if (Doc.HasMember("playerName") && Doc["playerName"].IsString())
{
UE_LOG(LogTemp, Log, TEXT("Player Name: %s"), UTF8_TO_TCHAR(Doc["playerName"].GetString()));
}
// 其他成员读取...
}
}
RapidJSON 的 API 与 UE4 内置的 JSON 类不同,更接近原生 C++ 风格,性能通常更好,但学习曲线可能稍陡。
注意事项
- 文件路径:确保 JSON 文件的路径正确,可以使用
FPaths::ProjectDir()获取项目根目录,或使用



还没有评论,来说两句吧...