UE4内部提供了非常简便的下载文件的方式.通过发送HTTPRequest来进行下载,下载完成以后执行HTTPResponse的Delegate函数就可以了..
参考资料在这里
步骤如下:
1.由于我们将要用到和HTTP有关的东西,同时我们接收完文件之后还希望转成JSON的数据格式,所以依赖库里面应该加入其它的依赖项.
打开 项目名.Build.cs文件
所以修改这句话为如下所示
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Http", "Json", "JsonUtilities" });
2.编写代码HTTPActor.cpp,头文件没什么好说的,就不贴了.记得引入"Runtime/Online/HTTP/Public/Http.h"就可以了.
#include "RoomEditor.h"
#include "HttpActor.h"
#include "UnrealString.h"
// Sets default values
AHttpActor::AHttpActor(const class FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
//When the object is constructed, Get the HTTP module
Http = &FHttpModule::Get();
}
// Called when the game starts or when spawned
void AHttpActor::BeginPlay()
{
MyHttpCall();
Super::BeginPlay();
}
/*Http call*/
void AHttpActor::MyHttpCall()
{
//创建HTTP请求
TSharedRef<IHttpRequest> Request = Http->CreateRequest();
//设置下载完成的Delegate函数
Request->OnProcessRequestComplete().BindUObject(this, &AHttpActor::OnResponseReceived);
//设置每帧的Update Delegate函数
Request->OnRequestProgress().BindUObject(this, &AHttpActor::OnRequestUpdate);
//URL
Request->SetURL("http://localhost/icons/testJson");
//请求的类型
Request->SetVerb("GET");
//其他参数
Request->SetHeader(TEXT("User-Agent"), "X-UnrealEngine-Agent");
Request->SetHeader("Content-Type", TEXT("application/json"));
//请求发送,开始加载请求的文件
Request->ProcessRequest();
}
/*加载完成后的回调*/
void AHttpActor::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
//Create a pointer to hold the json serialized data
TSharedPtr<FJsonObject> JsonObject;
if (bWasSuccessful)
{
UE_LOG(LogClass, Log, TEXT("DownLoad file Successed!!"))
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Response->GetContentAsString());
//反序列化,数据解析
if (FJsonSerializer::Deserialize(Reader, JsonObject))
{
TArray<TSharedPtr<FJsonValue>> array = JsonObject->GetArrayField("wall");
for (auto& jsonValue : array)
{
const TSharedPtr<FJsonObject>* innerObject;
if(jsonValue->TryGetObject(innerObject))
{
FString pos = innerObject->Get()->GetStringField("Pos");
UE_LOG(LogClass,Log,TEXT("Pos %s"), *pos);
FString name = innerObject->Get()->GetStringField("Name");
UE_LOG(LogClass, Log, TEXT("Name %s"), *name);
TArray<TSharedPtr<FJsonValue>> windows = innerObject->Get()->GetArrayField("Windows");
for (auto& window : windows)
{
const TSharedPtr<FJsonObject>* windowObj;
if(window->TryGetObject(windowObj))
{
FString pos = windowObj->Get()->GetStringField("Pos");
UE_LOG(LogClass, Log, TEXT("Window Pos %s"), *pos);
FString name = windowObj->Get()->GetStringField("Name");
UE_LOG(LogClass, Log, TEXT("Window Name %s"), *name);
}
}
}
}
}
}
else
{
UE_LOG(LogClass, Error, TEXT("Cannot DownLoad Files"));
}
}
//加载过程中每帧的回调
void AHttpActor::OnRequestUpdate(FHttpRequestPtr Request, int num1,int num2)
{
UE_LOG(LogClass,Log,TEXT("Now Download State %d , %d"),num1,num2);
}
步骤基本如下:
(1).创建HTTP请求
(2).设置参数,包括回调函数等
(3).发送请求
(4).下载完成后进行数据解析
其中,JSON的解析思路主要是这样的.
由于JSON可能包含有多层的嵌套,所以UE4的程序员在设计的时候提供了FJSONObject这一个类.他就表示一个复杂的JSON元素.
对于JSON元素,我们可以通过TeyGetObject来尝试将其转化为一个OBJECT,这样子我们就可以获取OBJECT内部的其他属性了.如果只是一个简单的KEY VALUE属性的话,就直接GET值就可以了...
另一点就是TArray,由于一个标签对应的值可能有很多个,所以要将其转为ARRAY,然后遍历进行下一步的解析才可以...
附上测试数据和输出结果
测试数据:
{"wall":[
{"Pos":"0,0,0", "Name":"wall1","Windows":[
{"Pos":"100,100,100","Name":"window1"},
{"Pos":"1000,1000,1000","Name":"window2"}
]}
]}
输出结果:
PS:和标题可能有点出入,因为做到这里并没有真正的下载文件..如果要将文件保存到本地,,那就再加个文件的IO就可以了...在这里就不废话了..下次见...
Tags:UE4 下载 JSON JSON解析 UE4学习