【问题标题】:Unreal Engine 4: dynamic multicast delegate binding虚幻引擎 4:动态多播委托绑定
【发布时间】:2018-12-30 18:46:54
【问题描述】:

目前我正在使用虚幻引擎的 HTTP 模块并编写了一个类来从 Web 服务中查询天气信息。 首先,我创建了一个像这样的通用 HTTP 服务类:

#pragma once

#include "CoreMinimal.h"
#include "Runtime/Online/HTTP/Public/Http.h"
#include "Json.h"
#include "HTTPService.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FHTTPOnResponseRecievedDelegate, const FString&, HttpData);

UCLASS()
class THMVRAYPLUGIN_API UHTTPService : public UClass
{
    GENERATED_BODY()

private:
    FHttpModule * Http;
    FString AuthorizationHeader = "Authorization";
    void SetAuthorizationHash(FString Hash, TSharedRef<IHttpRequest>& Request);
    void SetRequestHeaders(TSharedRef<IHttpRequest>& Request);
    bool ResponseIsValid(FHttpResponsePtr Response, bool bWasSuccessful);
    virtual void OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccesful);
    void Send(TSharedRef<IHttpRequest>& Request);

public:    
    UHTTPService();
    FHTTPOnResponseRecievedDelegate responseReceived;
    TSharedRef<IHttpRequest> GetRequest(FString request);
};

我为 OnResponseReceived 事件声明了一个动态多播委托。 该方法广播接收到的 JSON 字符串:

void UHTTPService::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccesful)
{
    if (ResponseIsValid(Response, bWasSuccesful)) {
        FString JSONString = Response->GetContentAsString();
        UE_LOG(LogTemp, Warning, TEXT("Http Response: %s"), *JSONString);
        responseReceived.Broadcast(JSONString);
    }

}

之后,我为特定的 Web API 创建了 HTTPService 类的子类:

#pragma once

#include "CoreMinimal.h"
#include "HTTPService.h"
#include "HTTPWeatherService.generated.h"

UCLASS()
class THMVRAYPLUGIN_API UHTTPWeatherService : public UHTTPService
{
    GENERATED_BODY()

private:
    FString APIBaseURL = "xxxx";
    FString APIKey = "xxxx";

public:    
    UHTTPWeatherService();
    void queryWeatherAPIForCoords(float lat, float lon);

};

现在我想将它用于我编写的自定义演员。 在详细信息面板自定义中,我创建了一个自定义行来保存这样的按钮:

//....
        auto OnWeatherButtonClicked = [myActor]
        {
            float lat = myActor->latitude;
            float lon = myActor->longitude;
            UHTTPWeatherService * weatherService = NewObject<UHTTPWeatherService>();
            weatherService->queryWeatherAPIForCoords(lat, lon);
            return FReply::Handled();
        };

        experimentalGroup.AddWidgetRow()
            .ValueContent()
            [
                SNew(SButton)
                .Text(LOCTEXT("Current weather", "Get weather at current location"))
                .ToolTipText(LOCTEXT("Uses a web api to get information on the current weather at the current coords","Uses a web api to get information on the current weather at the current coords"))
                .OnClicked_Lambda(OnWeatherButtonClicked)
            ];
//...

当您单击按钮时,它会触发查询 Web api 的函数。 我现在要做的是将一个函数绑定到动态多播委托。 我想在收到响应时触发我的自定义演员的方法。 你会怎么做?什么是好的程序结构? 谁能提供一段代码作为参考?

​​​​​​​提前致谢=)

【问题讨论】:

  • 使用responseReceived.AddDynamic 将您的对象注册到委托。但是,您的服务可能会被垃圾回收,请将对它的引用保存为您的课程中的UPROPERTY
  • @Rotem 我已经这样尝试过了。我没有收到任何编译错误,但虚幻引擎崩溃了。你能提供一些参考代码吗?
  • 多播委托的参考实现很容易在网上和引擎源代码中找到。引擎在哪里崩溃了?
  • @Rotem 引擎在启动时立即崩溃。我所做的是以下内容; 1) 我添加了 UPROPERTY 来保存天气服务类 UPROPERTY() class UHTTPWeatherService * weatherService = NewObject&lt;UHTTPWeatherService&gt;(); 2) 我添加了一个 UFUNCTION,当收到响应时调用它 UFUNCTION() void logResponse(const FString&amp; response) 3) 我调用了 AddDynamic OnPostinitProperties void ATHMForVRayActor::PostInitProperties() { Super::PostInitProperties(); weatherService-&gt;responseReceived.AddDynamic(this, &amp;ATHMForVRayActor::logResponse); }
  • 尽量不要在字段初始化器中构造您的对象,但仅在需要时。请记住,虚幻引擎中有 CDO。

标签: c++ unreal-engine4


【解决方案1】:

我设法使它与DECLARE_MULTICAST_DELEGATE_OneParam而不是DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam一起工作。

【讨论】:

    猜你喜欢
    • 2019-11-11
    • 2018-05-28
    • 1970-01-01
    • 2020-07-24
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    • 2015-07-03
    相关资源
    最近更新 更多