如何在 UE4 C++ 中使用参数将 UFunction 添加到接口的委托?

How to add a UFunction to an interface's delegate with parameters in UE4 C++?

我想在 Unreal 中使用网络套接字。我正在按照此处找到的教程进行操作:Web Socket Tutorial

最值得注意的是,我试图在连接之前绑定到事件。在示例中,他们使用 .AddLambda 但是,我想尝试使用 .AddUFunction。该函数似乎接受了对象、函数名称和 VarTypes ...types。对于使用参数的代表,我似乎无法弄清楚最后一个参数是什么。 (至少我相信这就是问题所在)函数本身具有正确的签名并且与我要绑定的委托相匹配。

这是我目前的情况:

void AWebSocketController::CreateWebSocket(FString ServerUrl, FString ServerProtocol)
{
  Socket = FWebSocketsModule::Get().CreateWebSocket(ServerUrl, ServerProtocol);

  // We bind to the events
  Socket->OnConnected().AddUFunction(this, FName("OnSocketConnection"));

  Socket->OnConnectionError().AddUFunction(this, FName("OnSocketConnectionError"));

  Socket->OnClosed().AddUFunction(this, FName("OnSocketClosed"));

  Socket->OnMessage().AddUFunction(this, FName("OnSocketReceiveMessage"));

  Socket->OnMessageSent().AddUFunction(this, FName("OnSocketSentMessage"));

  // And we finally connect to the server. 
  Socket->Connect();

}

它给我以下错误信息:

error LNK2005: "public: void __cdecl AWebSocketController::OnSocketClosed(int,class FString const &,bool)" (?OnSocketClosed@AWebSocketController@@QEAAXHAEBVFString@@_N@Z) already defined in WebSocketController.cpp.obj
error LNK2005: "public: void __cdecl AWebSocketController::OnSocketConnection(void)" (?OnSocketConnection@AWebSocketController@@QEAAXXZ) already defined in WebSocketController.cpp.obj
error LNK2005: "public: void __cdecl AWebSocketController::OnSocketConnectionError(class FString const &)" (?OnSocketConnectionError@AWebSocketController@@QEAAXAEBVFString@@@Z) already defined in WebSocketController.cpp.obj
error LNK2005: "public: void __cdecl AWebSocketController::OnSocketReceiveMessage(class FString const &)" (?OnSocketReceiveMessage@AWebSocketController@@QEAAXAEBVFString@@@Z) already defined in WebSocketController.cpp.obj
error LNK2005: "public: void __cdecl AWebSocketController::OnSocketSentMessage(class FString const &)" (?OnSocketSentMessage@AWebSocketController@@QEAAXAEBVFString@@@Z) already defined in WebSocketController.cpp.obj

函数定义:

void AWebSocketController::OnSocketConnection()
{
}

void AWebSocketController::OnSocketConnectionError(const FString& ErrorMessage)
{
}

void AWebSocketController::OnSocketClosed(int32 StatusCode, const FString& Reason, bool WasClean)
{
}

void AWebSocketController::OnSocketReceiveMessage(const FString& Message)
{
}

void AWebSocketController::OnSocketSentMessage(const FString& Message)
{
}

我以前从未遇到过这个 .AddUFunction,而且我似乎找不到任何有关如何使用它的示例。如果有人能帮助我或指出正确的方向,我将不胜感激。

请阅读 Events

上的文档

您必须在您的 class 中声明与事件委托相匹配的函数签名,函数指针将被绑定。

上面的示例图片来自引擎源。

适合我!

SandboxGameInstance.cpp

#include "SandboxGameInstance.h"

#include "WebSocketsModule.h"
#include "IWebSocket.h"       // Socket definition
void USandboxGameInstance::Init()
{
    Super::Init();
    FWebSocketsModule& Module = FModuleManager::LoadModuleChecked<FWebSocketsModule>(TEXT("WebSockets"));

    const FString ServerURL = TEXT("ws://127.0.0.1:3000/"); // Your server URL. You can use ws, wss or wss+insecure.
    const FString ServerProtocol = TEXT("ws");              // The WebServer protocol you want to use.

    TSharedPtr<IWebSocket> Socket = FWebSocketsModule::Get().CreateWebSocket(ServerURL, ServerProtocol);

    // We bind to the events
    Socket->OnConnected().AddUFunction(this, FName("OnSocketConnection"));

    Socket->OnConnectionError().AddUFunction(this, FName("OnSocketConnectionError"));

    Socket->OnClosed().AddUFunction(this, FName("OnSocketClosed"));

    Socket->OnMessage().AddUFunction(this, FName("OnSocketReceiveMessage"));

    Socket->OnMessageSent().AddUFunction(this, FName("OnSocketSentMessage"));

    // And we finally connect to the server. 
    Socket->Connect();
}

void USandboxGameInstance::OnSocketConnection()
{
    UE_LOG(LogTemp, Warning, TEXT("CONNECTED"));
}

void USandboxGameInstance::OnSocketConnectionError(const FString& ErrorMessage)
{
    UE_LOG(LogTemp, Warning, TEXT("ERROR"));
}

void USandboxGameInstance::OnSocketClosed(int32 StatusCode, const FString& Reason, bool WasClean)
{
    UE_LOG(LogTemp, Warning, TEXT("CLOSED"));
}

void USandboxGameInstance::OnSocketReceiveMessage(const FString& Message)
{
    UE_LOG(LogTemp, Warning, TEXT("RECEIVED"));
}

void USandboxGameInstance::OnSocketSentMessage(const FString& Message)
{
    UE_LOG(LogTemp, Warning, TEXT("SENT"));
}

SandboxGameInstance.h

#pragma once

#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "SandboxGameInstance.generated.h"

UCLASS()
class SANDBOX_API USandboxGameInstance : public UGameInstance
{
    GENERATED_BODY()
public:
    virtual void Init() override;

    UFUNCTION()
    void OnSocketConnection();

    UFUNCTION()
    void OnSocketConnectionError(const FString& ErrorMessage);

    UFUNCTION()
    void OnSocketClosed(int32 StatusCode, const FString& Reason, bool WasClean);

    UFUNCTION()
    void OnSocketReceiveMessage(const FString& Message);

    UFUNCTION()
    void OnSocketSentMessage(const FString& Message);
};