You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UE5.1.1中跨类Delegate广播后未触发绑定函数的问题

Unreal Engine 5.1.1 动态多播代理未触发问题排查

问题场景

在UE5.1.1开发中,UWebSocketHandler类的OnMessageReceived动态多播代理完成广播后,未触发UCustomGameInstanceBase类中的HandleMessageReceived函数。已确认HandleWebSocketConnected方法正常执行并广播消息,且UCustomGameInstanceBase中的ConnectToWebSocket已完成代理绑定操作。

相关代码

UCustomGameInstanceBase.h

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMessageReceivedBP, const FString&, Message);

UCLASS()
class SomeProjectName_API UCustomGameInstanceBase : public UGameInstance
{
    ...
    UPROPERTY(BlueprintAssignable, Category = "WebSocket")
    FOnMessageReceivedBP OnMessageReceivedBP;
    ...
    void HandleMessageReceived(const FString& Message);
};

UCustomGameInstanceBase.cpp

void UCustomGameInstanceBase::ConnectToWebSocket()
{
    if (WebSocketMgr)
    {
        WebSocketMgr->OnMessageReceived.AddDynamic(this, &UCustomGameInstanceBase::HandleMessageReceived);
        WebSocketMgr->ConnectToWebSocket(AccessToken, WSUrl);
    }
}

void UCustomGameInstanceBase::HandleMessageReceived(const FString& Message)
{
    UE_LOG(LogTemp, Log, TEXT("HandleMessageReceived!!!"));
    OnMessageReceivedBP.Broadcast(Message);
}

UWebSocketHandler.h

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMessageReceivedDelegate, const FString&, Message);
UCLASS(Blueprintable)
class SomeProjectName_API UWebSocketHandler : public UObject
{
    ...
    UPROPERTY(BlueprintAssignable, Category = "WebSocket")
    FOnMessageReceivedDelegate OnMessageReceived;
    ...
};

UWebSocketHandler.cpp

void UWebSocketHandler::HandleWebSocketConnected()
{
    ...
    OnMessageReceived.Broadcast(messageString);
}

可能的原因及解决方法

  • 绑定函数未标记为UFUNCTION:Unreal的AddDynamic依赖反射系统,只有标记为UFUNCTION()的成员函数才能被动态代理正确绑定。修改UCustomGameInstanceBase.h中的函数声明:

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

    未添加此宏时,绑定会静默失败,无报错但代理不会生效。

  • 对象实例不匹配:确认绑定代理的WebSocketMgr实例与执行广播的UWebSocketHandler是同一个对象。可在绑定和广播处添加日志打印指针地址验证:

    // 绑定处(UCustomGameInstanceBase.cpp)
    UE_LOG(LogTemp, Log, TEXT("绑定代理的WebSocketMgr地址: %p"), WebSocketMgr);
    // 广播处(UWebSocketHandler.cpp)
    UE_LOG(LogTemp, Log, TEXT("广播代理的UWebSocketHandler地址: %p"), this);
    

    若地址不一致,说明绑定的是其他实例,需检查WebSocketMgr的初始化逻辑,确保绑定的是后续执行广播的实例。

  • 生命周期异常:检查UCustomGameInstanceBase或UWebSocketHandler的生命周期:

    • 若WebSocketMgr在绑定后被销毁重建,原绑定会失效,需在重建后重新绑定代理;
    • 若UCustomGameInstanceBase在广播时已被销毁(GameInstance生命周期通常较长,但仍需确认),代理绑定会被自动移除。
  • 线程安全问题:Unreal动态多播代理默认要求在GameThread执行广播。若HandleWebSocketConnected在非GameThread调用,需将广播逻辑切换到GameThread:

    void UWebSocketHandler::HandleWebSocketConnected()
    {
        ...
        AsyncTask(ENamedThreads::GameThread, [this, messageString]()
        {
            OnMessageReceived.Broadcast(messageString);
        });
    }
    

    可通过check(IsInGameThread())在HandleWebSocketConnected开头验证当前线程是否为GameThread。

  • 绑定时机过晚:确认代理绑定操作在HandleWebSocketConnected广播之前完成。若WebSocket已连接成功后才执行绑定,此时广播已经发生,只有后续的广播才会触发绑定函数,需调整绑定时机,确保在调用ConnectToWebSocket前完成绑定。

内容的提问来源于stack exchange,提问作者Rasik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:43:16