虚幻引擎 Call Event Dispatcher 节点

一、基础概念区分

  1. Event Dispatcher(事件分发器):蓝图内自定义的广播通道,相当于消息中转站。
  2. Call Event Dispatcher(Broadcast 广播节点)Call Event Dispatcher 就是分发器自带的 Broadcast 节点,作用:主动发送消息、传递参数,所有提前 Bind Event 绑定过的对象都会收到这条消息并执行自身回调逻辑。
  3. 完整流程闭环:
    1. 创建事件分发器(定义消息参数)
    2. A 对象:Call Event Dispatcher(Broadcast)发消息
    3. B/C/D 对象:Bind Event 订阅消息
    4. 不需要监听时:Unbind Event 取消订阅

关键特性

  • 一对多广播:一次 Broadcast,所有绑定对象同时触发回调
  • 支持传递自定义参数(int、bool、Actor、向量、结构体等)
  • 解耦代码:发送方不需要知道有哪些监听者,降低蓝图耦合

二、案例需求

做玩家拾取金币加分系统,完整流程:
  1. 金币 Actor(发送方):碰撞触发 → Call Event Dispatcher 广播加分消息(传递金币分值)
  2. 玩家蓝图(监听方):游戏开始绑定分发器事件,收到广播自动增加分数
  3. 兜底逻辑:玩家销毁时 Unbind 防止崩溃

三、分步详细操作(UE5.1~5.7 通用)

第一部分:创建全局消息载体 GameInstance(存放事件分发器)

把分发器放在 GameInstance,实现全局任意 Actor 都能广播 / 监听

步骤 1:新建 GameInstance 蓝图

  1. 内容浏览器右键 → 蓝图类 → 搜索 Game Instance → 命名 GI_GameMain
  2. 打开蓝图,切换到【我的蓝图】面板
  3. 新建事件分发器:
    • 点「+ 事件分发器」,命名 OnCoinPickUp
    • 右键分发器 → 添加参数:

      参数名:CoinValue,类型:整数 Integer

作用:广播时可以传递本次拾取金币的分数

步骤 2:项目设置指定自定义 GameInstance

  1. 顶部菜单栏:编辑 → 项目设置 → 地图 & 模式 → 游戏实例
  2. 游戏实例类选择刚才创建的 GI_GameMain,保存设置
  3. 编译蓝图

第二部分:创建发送方 BP_Coin(金币,核心使用 Call Event Dispatcher)

步骤 1:创建金币 Actor 蓝图

  1. 右键蓝图类 → Actor → BP_Coin
  2. 添加组件:StaticMesh(金币模型)、Sphere Collision(球形碰撞盒)
  3. 新建变量:
    • CoinScore 整数,默认值 10,公开,用来设置单个金币分值

步骤 2:获取 GameInstance 引用

Event Graph 空白处右键搜索 Get Game Instance

输出引脚提升转换为 GI_GameMain 类型,命名 MainGI

步骤 3:制作碰撞拾取逻辑 + Call Event Dispatcher(Broadcast)

  1. 添加事件:Event Actor BeginOverlap(玩家走进碰撞触发拾取)
  2. 过滤碰撞对象:

    从重叠 Actor 拖出 Cast To BP_Player,判断是不是玩家,失败则直接结束流程

  3. 核心:Call Event Dispatcher(Broadcast 广播节点)
    • MainGI(GameInstance 引用)引脚拖出,搜索分发器名称 OnCoinPickUp
    • 选择 Call OnCoinPickUp(也就是你说的 Call Event Dispatcher,官方显示为 Broadcast)
  4. 参数赋值:CoinValue 引脚连接本地变量 CoinScore
  5. 广播后销毁金币:Broadcast 输出执行线连接 Destroy Actor

完整执行线:

Event Actor BeginOverlap → Cast 玩家成功 → Get MainGI → Call OnCoinPickUp (CoinValue=CoinScore) → Destroy Actor

这里的 Call OnCoinPickUp 就是Call Event Dispatcher 节点,功能是对外广播消息

第三部分:创建监听方 BP_Player(玩家,Bind 订阅广播)

步骤 1:玩家蓝图基础设置

  1. 蓝图类 → 第三人称角色 → BP_Player
  2. 新建变量:
    • PlayerScore 整数,默认 0(存储玩家总分)

步骤 2:创建回调自定义事件(接收广播参数)

我的蓝图面板 → 新建自定义事件 UpdateScore

添加参数:InAddScore 整数(接收金币传递的分值)

事件内部逻辑:

PlayerScore = PlayerScore + InAddScore

添加 Print String 打印当前总分,用于测试查看

步骤 3:游戏开始 Bind Event 订阅分发器

  1. 事件 Event BeginPlay
  2. Get Game Instance 转为 GI_GameMain → MainGI
  3. 从 MainGI 拖出 → Bind Event to OnCoinPickUp
  4. Event 引脚选择自定义事件 UpdateScore

    执行线:Event BeginPlay → Bind Event

步骤 4:销毁时 Unbind Event(防崩溃必备)

  1. 事件 Event Destroyed
  2. 同样获取 MainGI
  3. 拖出 Unbind Event from OnCoinPickUp,Event 依旧选 UpdateScore

    执行线:Event Destroyed → Unbind Event

四、关卡部署与测试步骤

  1. 关卡放入 BP_Player(自动生成第三人称玩家)
  2. 拖入多个 BP_Coin 金币,可在细节面板修改每个金币 CoinScore 分值(10/20/50)
  3. 全部蓝图编译保存
  4. 运行游戏:
    1. 操控玩家走到金币碰撞范围
    2. 金币执行 Call Event Dispatcher 广播分值
    3. 玩家绑定的 UpdateScore 事件自动触发,分数累加打印
    4. 金币自动销毁,多次拾取分数持续上涨

五、Call Event Dispatcher 节点完整参数详解

Call OnCoinPickUp 为例:
  1. Execute(输入执行):触发广播的执行线(碰撞、按键、定时器等)
  2. Target(对象):分发器所在载体(GameInstance/Actor/Widget 引用)
  3. 自定义参数引脚:创建分发器时添加的参数,广播时向外传递数据
  4. Completed(输出执行):广播完成后执行后续逻辑(销毁物体、播放特效、播放音效)

六、两种分发器存放载体使用区别

方案 1:分发器放在 GameInstance(本案例)

适用:全局消息(得分、玩家死亡、游戏通关、全局 UI 更新)

优点:任意 Actor 随时调用 Call Event Dispatcher,无需获取特定 Actor 引用

方案 2:分发器放在单个 Actor(开关 / 门等交互物)

适用:局部交互(开关灯光、开门)

操作:需要先通过 Get All Actors of Class 获取目标 Actor 引用,再拖出 Call Event Dispatcher 广播

示例:BP_Door 门 Actor 内置 OnOpenDoor 分发器,按下 E 键执行 Call OnOpenDoor 广播

七、完整蓝图逻辑文字梳理

1. 发送方 BP_Coin(Call Event Dispatcher 核心)

plaintext
Event Actor BeginOverlap
    → Cast To BP_Player (成功分支)
        → Get Game Instance 转 GI_GameMain (MainGI)
            → Call OnCoinPickUp (CoinValue = CoinScore) // Call Event Dispatcher广播
                → Destroy Actor

2. 全局载体 GI_GameMain

仅定义事件分发器 OnCoinPickUp(int CoinValue),无额外逻辑

3. 监听方 BP_Player

plaintext
// 订阅广播
Event BeginPlay
    → Get MainGI
        → Bind Event to OnCoinPickUp (Event=UpdateScore)

// 回调接收消息
Custom Event UpdateScore(InAddScore)
    → PlayerScore += InAddScore
    → Print String 输出总分

// 取消订阅
Event Destroyed
    → Get MainGI
        → Unbind Event from OnCoinPickUp (Event=UpdateScore)

八、高频报错 & 踩坑解决

1. Call Event Dispatcher 节点找不到

原因:没有拿到分发器所属对象的正确引用

解决:先 Get GameInstance / Get 对应 Actor,转换对应蓝图类型,再拖出才能看到 Call 节点

2. 广播后监听事件完全不触发

排查点:
  1. Bind Event 是否成功执行(打印日志验证 BeginPlay 绑定)
  2. 广播参数类型和回调事件参数是否匹配
  3. 广播对象 Target 与绑定对象 Target 是同一个实例
  4. 监听 Actor 是否已经销毁(销毁会自动失效绑定)

3. 多次拾取分数翻倍叠加

原因:多次重复 Bind Event

解决:绑定前增加判断节点 Is Bound To Event,已绑定就跳过 Bind 逻辑

4. 切换关卡 / 销毁对象游戏崩溃

原因:对象销毁前没有 Unbind Event,分发器还持有已销毁对象的回调引用

解决:所有动态 Actor、Widget 在 Event Destroyed 内强制解绑

九、拓展案例:UI Widget 使用 Call Event Dispatcher

  1. GameInstance 创建 OnShowTip 分发器,参数文本
  2. 任意角色 / 道具触发:Call OnShowTip 传递提示文字
  3. UI 界面在 Construct 绑定事件,收到广播弹出提示框
  4. UI 关闭时 Destruct 执行 Unbind,避免 UI 销毁后广播崩溃

十、规范使用总结

  1. Call Event Dispatcher = Broadcast 广播,是分发器对外发送消息唯一节点
  2. 发送方只负责 Call 广播,不用关心谁在监听,代码解耦
  3. 一对多优势:一次 Call,所有 Bind 过的对象同步执行逻辑
  4. 配对规则:Bind 订阅 → Call 广播触发 → Unbind 取消订阅,动态对象必须成对使用

感谢您的来访,获取更多精彩文章请收藏本站。

THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容