当前位置:   article > 正文

【虚幻引擎】UE4 Http之异步请求数据_虚幻蓝图http节点

虚幻蓝图http节点

B站教学链接:https://space.bilibili.com/449549424?spm_id_from=333.1007.0.0


一、BlueprintAsyncActionBase

  UE提供了BlueprintAsyncActionBase类,实现异步加载的方式请求数据

虚幻的很多蓝图节点都采用了异步加载的方式

比如:延迟Delay,PlayMontage都是采用异步加载的方式进行实现

接下我们就用异步加载的方式实现HTTP请求下载

二、HTTP请求

新建一个C++项目,然后build.cs加入模块

		PrivateDependencyModuleNames.AddRange(new string[] { "HTTP", "Json" });

 创建继承自BlueprintAsyncActionBase的C++类

请求的Json格式的数据为

 代理声明:代理参数跟我们后面函数的输出参数有关,要想输出函数参数,需要在代理的位置声明返回参数

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FRequestCompleteDelegate, const TArray<FNewsItem>&, Data,int32, ver);

 

 输出节点如OnSucceeded,OnFailed这些节点跟我们声明的代理有关,就是代理声明的对象

  1. //输出节点
  2. UPROPERTY(BlueprintAssignable)
  3. FRequestCompleteDelegate OnSucceeded;
  4. //输出节点
  5. UPROPERTY(BlueprintAssignable)
  6. FRequestCompleteDelegate OnFailed;

 

 主要代码如下MyBlueprintAsyncActionBase.h文件

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2. #pragma once
  3. #include "CoreMinimal.h"
  4. #include "Kismet/BlueprintAsyncActionBase.h"
  5. #include "Interfaces/IHttpRequest.h"
  6. #include "MyBlueprintAsyncActionBase.generated.h"
  7. USTRUCT(BlueprintType)
  8. struct FNewsItem {
  9. GENERATED_USTRUCT_BODY()
  10. FNewsItem() {}
  11. FNewsItem(FString _Path, FString _Url)
  12. : Path(_Path), Url(_Url) {}
  13. UPROPERTY(BlueprintReadOnly)
  14. FString Path;
  15. UPROPERTY(BlueprintReadOnly)
  16. FString Url;
  17. };
  18. DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FRequestCompleteDelegate, const TArray<FNewsItem>&, Data,int32, ver);
  19. /**
  20. *
  21. */
  22. UCLASS()
  23. class TEST111_API UMyBlueprintAsyncActionBase : public UBlueprintAsyncActionBase
  24. {
  25. GENERATED_BODY()
  26. UMyBlueprintAsyncActionBase();
  27. //json
  28. public:
  29. // 自定义的异步蓝图节点
  30. UFUNCTION(BlueprintCallable, Category = "AsyncHttp", meta = (BlueprintInternalUseOnly = "true"))
  31. static UMyBlueprintAsyncActionBase* AsyncHttpURLRequest(const FString& url);
  32. void HttpRequestStar(const FString& url);
  33. void HttpRequest_RecHandle(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful);
  34. //输出节点
  35. UPROPERTY(BlueprintAssignable)
  36. FRequestCompleteDelegate OnSucceeded;
  37. //输出节点
  38. UPROPERTY(BlueprintAssignable)
  39. FRequestCompleteDelegate OnFailed;
  40. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Version")
  41. int32 version;
  42. };

MyBlueprintAsyncActionBase.cpp文件

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2. #include "MyBlueprintAsyncActionBase.h"
  3. #include "HttpModule.h"
  4. #include "Interfaces/IHttpResponse.h"
  5. UMyBlueprintAsyncActionBase::UMyBlueprintAsyncActionBase()
  6. {
  7. if (HasAnyFlags(RF_ClassDefaultObject) == false)
  8. {
  9. AddToRoot(); //防止自动GC
  10. }
  11. }
  12. UMyBlueprintAsyncActionBase* UMyBlueprintAsyncActionBase::AsyncHttpURLRequest(const FString& url) {
  13. UMyBlueprintAsyncActionBase* AsyncHttpObject = NewObject<UMyBlueprintAsyncActionBase>();
  14. AsyncHttpObject->HttpRequestStar(url);
  15. return AsyncHttpObject;
  16. }
  17. //开始请求
  18. void UMyBlueprintAsyncActionBase::HttpRequestStar(const FString& url)
  19. {
  20. TSharedRef<IHttpRequest, ESPMode::ThreadSafe> request = FHttpModule::Get().CreateRequest();
  21. request->SetVerb("GET");
  22. request->SetURL(url);
  23. //request->SetHeader(TEXT("Content-Type"), TEXT("application/json;charset=utf-8"));
  24. //request->SetTimeout(200);
  25. //request->SetContentAsString(requestJsonStr); POST时候用
  26. //request->OnRequestProgress().BindUObject() 绑定进度
  27. request->OnProcessRequestComplete().BindUObject(this, &UMyBlueprintAsyncActionBase::HttpRequest_RecHandle); //请求回调
  28. request->ProcessRequest();
  29. }
  30. //请求回调
  31. void UMyBlueprintAsyncActionBase::HttpRequest_RecHandle(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful) {
  32. if (bWasSuccessful && response.IsValid() && EHttpResponseCodes::IsOk(response->GetResponseCode())) {
  33. TSharedPtr<FJsonObject> jsonObj;
  34. TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(response->GetContentAsString());
  35. if (FJsonSerializer::Deserialize(JsonReader, jsonObj)) {
  36. version = jsonObj->GetIntegerField("versionId");
  37. UE_LOG(LogTemp, Warning, TEXT("version is %d"), version);
  38. const TArray< TSharedPtr<FJsonValue> >* dataList;
  39. if (jsonObj->TryGetArrayField(TEXT("DataList"), dataList)) // 获取数组
  40. {
  41. TArray<FNewsItem> newsList;
  42. for (TSharedPtr<FJsonValue> item : *dataList)
  43. {
  44. TSharedPtr<FJsonObject>itemObjet = item->AsObject();
  45. newsList.Add(FNewsItem(
  46. itemObjet->GetStringField(TEXT("Path")),
  47. itemObjet->GetStringField(TEXT("Url"))
  48. ));
  49. }
  50. OnSucceeded.Broadcast(newsList, version); // 成功的执行
  51. RemoveFromRoot();
  52. return;
  53. }
  54. }
  55. }
  56. OnFailed.Broadcast({},0); // 失败的执行
  57. RemoveFromRoot();
  58. }

打开关卡蓝图:

 三、HTTP下载

这里我重新建了一个继承自BlueprintAsyncActionBase的类

TestBlueprintAsyncActionBase.h文件

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2. #pragma once
  3. #include "CoreMinimal.h"
  4. #include "Kismet/BlueprintAsyncActionBase.h"
  5. #include "Interfaces/IHttpRequest.h"
  6. #include "TestBlueprintAsyncActionBase.generated.h"
  7. /**
  8. *
  9. */
  10. DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FDownloadProgressDelegate1,
  11. const int32&, ReceivedDataInBytes,
  12. const int32&, TotalDataInBytes,
  13. const TArray<uint8>&, BinaryData
  14. );
  15. DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDownloadDelegate1);
  16. UCLASS()
  17. class TEST111_API UTestBlueprintAsyncActionBase : public UBlueprintAsyncActionBase
  18. {
  19. GENERATED_BODY()
  20. UTestBlueprintAsyncActionBase();
  21. public:
  22. //load data
  23. UFUNCTION(BlueprintCallable, Category = "MyAsyncHttp", meta = (BlueprintInternalUseOnly = "true"))
  24. static UTestBlueprintAsyncActionBase* AsyncHttpDownload(const FString& url);
  25. void DownloadRequestStart(const FString& url);
  26. void DownloadRequestHandle(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful);
  27. void DownloadProgress(FHttpRequestPtr request, int32 bytesSent, int32 bytesReceived);
  28. //输出节点
  29. UPROPERTY(BlueprintAssignable)
  30. FDownloadProgressDelegate1 OnProgressUpdate; //最好把有参数的放在前面,不然参数在蓝图节点有时候被吃掉了
  31. //输出节点
  32. UPROPERTY(BlueprintAssignable)
  33. FDownloadDelegate1 Load_Ok;
  34. //输出节点
  35. UPROPERTY(BlueprintAssignable)
  36. FDownloadDelegate1 Load_Fail;
  37. };

TestBlueprintAsyncActionBase.cpp文件 

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2. #include "TestBlueprintAsyncActionBase.h"
  3. #include "HttpModule.h"
  4. #include "Interfaces/IHttpResponse.h"
  5. UTestBlueprintAsyncActionBase::UTestBlueprintAsyncActionBase()
  6. {
  7. if (HasAnyFlags(RF_ClassDefaultObject) == false)
  8. {
  9. AddToRoot(); //防止自动GC
  10. }
  11. }
  12. UTestBlueprintAsyncActionBase* UTestBlueprintAsyncActionBase::AsyncHttpDownload(const FString& url)
  13. {
  14. UTestBlueprintAsyncActionBase* AsyncHttpObject = NewObject<UTestBlueprintAsyncActionBase>();
  15. AsyncHttpObject->DownloadRequestStart(url);
  16. return AsyncHttpObject;
  17. }
  18. void UTestBlueprintAsyncActionBase::DownloadRequestStart(const FString& url)
  19. {
  20. TSharedRef<IHttpRequest, ESPMode::ThreadSafe> request = FHttpModule::Get().CreateRequest();
  21. request->SetVerb("GET");
  22. request->SetURL(url);
  23. request->OnProcessRequestComplete().BindUObject(this, &UTestBlueprintAsyncActionBase::DownloadRequestHandle); //请求回调
  24. request->OnRequestProgress().BindUObject(this, &UTestBlueprintAsyncActionBase::DownloadProgress);// 下载进度
  25. request->ProcessRequest();
  26. RemoveFromRoot(); // 手动GC
  27. }
  28. void UTestBlueprintAsyncActionBase::DownloadRequestHandle(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful)
  29. {
  30. RemoveFromRoot();
  31. if (bWasSuccessful && response.IsValid() && EHttpResponseCodes::IsOk(response->GetResponseCode()))
  32. {
  33. if (response->GetContentLength() > 0) {
  34. TArray<uint8> EmptyData;
  35. OnProgressUpdate.Broadcast(response->GetContentLength(), response->GetContentLength(), EmptyData);
  36. }
  37. FString FileSavePath = FPaths::ProjectDir() + "/download/gameplay.png";
  38. FString Path, Filename, Extension;
  39. FPaths::Split(FileSavePath, Path, Filename, Extension);
  40. IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
  41. if (!PlatformFile.DirectoryExists(*Path))
  42. {
  43. if (!PlatformFile.CreateDirectoryTree(*Path))
  44. {
  45. UE_LOG(LogTemp, Error, TEXT("Create Directory Failed!"));
  46. Load_Fail.Broadcast();
  47. return;
  48. }
  49. }
  50. IFileHandle* FileHandle = PlatformFile.OpenWrite(*FileSavePath);
  51. if (FileHandle)
  52. {
  53. FileHandle->Write(response->GetContent().GetData(), response->GetContentLength());
  54. delete FileHandle;
  55. Load_Ok.Broadcast();
  56. return;
  57. }
  58. else {
  59. UE_LOG(LogTemp, Error, TEXT("Save File Failed!"));
  60. Load_Fail.Broadcast();
  61. return;
  62. }
  63. }
  64. UE_LOG(LogTemp, Error, TEXT("download File Failed!"));
  65. Load_Fail.Broadcast();
  66. return;
  67. }
  68. void UTestBlueprintAsyncActionBase::DownloadProgress(FHttpRequestPtr request, int32 bytesSent, int32 bytesReceived)
  69. {
  70. if (request->GetResponse()->GetContentLength() > 0)
  71. {
  72. TArray<uint8> EmptyData;
  73. OnProgressUpdate.Broadcast(bytesReceived, request->GetResponse()->GetContentLength(), EmptyData);
  74. }
  75. }

打开关卡蓝图设置:

 注意这里图片下载的位置在项目工程里新建了一个download的文件夹里面

FString FileSavePath = FPaths::ProjectDir() + "/download/gameplay.png";

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/91179?site
推荐阅读
相关标签
  

闽ICP备14008679号