创游世界广播机制完全指南
一句话摘要
本文全面讲解创游世界广播机制的工作原理、使用场景、最佳实践和常见问题,帮助理解如何通过广播实现对象间的解耦通信。
适合谁阅读
- 刚学会基础脚本,想要理解对象间通信的创作者
- 遇到广播问题不知道怎么排查的开发者
- 想做复杂项目需要架构设计的进阶用户
你将学到什么
- 广播的基本概念和工作原理
- 广播的命名规范和使用场景
- 广播与直接改值的区别
- 广播在 UI 和地图逻辑中的配合方式
- 联机环境下广播的使用注意事项
- 常见广播问题排查方法
1. 什么是广播
1.1 广播的定义
广播是一种消息发布-订阅机制,用于对象间的解耦通信。当某个对象发送广播时,所有监听该广播的脚本都会执行,不需要发送者知道谁在监听。
1.2 广播的工作原理
发送广播 → 系统查找监听该广播的所有脚本 → 依次执行广播的核心特点:
| 特点 | 说明 |
|---|---|
| 解耦 | 发送者不需要知道谁在监听 |
| 一对多 | 一个广播可以触发多个对象的响应 |
| 异步 | 发送后不等待执行结果 |
| 名称匹配 | 监听者通过广播名称匹配接收消息 |
1.3 广播 vs 直接改值
| 对比项 | 广播 | 直接改值 |
|---|---|---|
| 耦合度 | 低(发送者不知道谁响应) | 高(发送者需要知道目标对象) |
| 扩展性 | 好(新增监听者不需要改发送者) | 差(新增目标需要改发送者) |
| 调试难度 | 中等(需要追踪广播名称) | 简单(直接知道谁改了什么) |
| 适用场景 | 事件通知、解耦通信 | 单目标数据同步 |
2. 广播的基本用法
2.1 发送广播
在脚本中使用积木块发送广播:
发送广播 "广播名称"或者带参数的广播:
发送广播 "道具_获得" 并携带文本 "金币"2.2 监听广播
在脚本中设置触发时机为「当收到广播时」,然后填写广播名称:
当收到广播 "道具_获得" 时
→ 执行相应逻辑2.3 广播的作用域
| 作用域 | 说明 |
|---|---|
| 当前地图 | 广播只在当前地图内传播 |
| 全局 | 系统级广播可在全局传播 |
| UI 广播 | UI 可以向地图发广播,地图处理后再通知 UI |
3. 广播命名规范
3.1 命名原则
良好的广播命名应该:
- 语义化:名称能表达发生的事情
- 分层:使用下划线或驼峰表示层级
- 统一:在项目中保持命名风格一致
3.2 推荐命名方式
| 类型 | 示例 | 说明 |
|---|---|---|
| 事件型 | 玩家_死亡 道具_获得 战斗_开始 | 表示发生了什么事情 |
| 动作型 | 打开门 切换地图 显示对话框 | 表示要执行什么动作 |
| 请求型 | 请求购买 请求使用 请求存档 | 表示需要处理某个请求 |
| 响应型 | 刷新UI 更新状态 同步数据 | 表示需要刷新或更新 |
3.3 不推荐的命名
| 不推荐 | 原因 |
|---|---|
刷新 | 太泛指,不知道刷新什么 |
更新 | 同样太泛指 |
1 2 a b | 无法从名称理解含义 |
send_broadcast_1 | 命名混乱,不易维护 |
4. 广播的典型使用场景
4.1 UI 通知地图处理
场景:玩家在 UI 界面上点击购买按钮,需要扣除金币。
错误做法:
UI 脚本:
当按钮被点击时
→ 直接修改玩家金币推荐做法:
UI 脚本:
当按钮被点击时
→ 发送广播 "请求购买" 并携带文本 "物品ID"
地图脚本:
当收到广播 "请求购买" 时
→ 检查金币是否足够
→ 如果足够,扣除金币并发放物品
→ 发送广播 "购买结果" 通知 UI
UI 脚本:
当收到广播 "购买结果" 时
→ 刷新 UI 显示4.2 一个事件触发多个响应
场景:敌人死亡时,需要同时播放死亡特效、更新任务进度、掉落物品。
敌人脚本:
当生命值变为 0 时
→ 发送广播 "敌人_死亡" 并携带文本 "敌人ID"
特效脚本:
当收到广播 "敌人_死亡" 时
→ 播放死亡动画
任务脚本:
当收到广播 "敌人_死亡" 时
→ 更新任务进度
掉落脚本:
当收到广播 "敌人_死亡" 时
→ 生成掉落物品4.3 跨对象通信
场景:点击一个物体,触发另一个物体的行为。
按钮脚本:
当互动按钮被按下时
→ 发送广播 "打开机关"
门脚本:
当收到广播 "打开门" 时
→ 播放开门动画4.4 状态同步
场景:需要让多个对象同时更新状态。
触发器脚本:
当满足条件时
→ 发送广播 "状态_更新"
所有监听者脚本:
当收到广播 "状态_更新" 时
→ 各自更新自己的显示5. 广播的高级用法
5.1 带参数的广播
广播可以携带参数,用于传递数据:
发送广播 "道具_获得" 并携带数字 100
发送广播 "玩家_受伤" 并携带数字 50
发送广播 "任务_完成" 并携带文本 "任务ID"监听时接收参数:
当收到广播 "道具_获得" 并携带数字 时
→ 获取道具数量
→ 显示获得提示5.2 广播的发送时机
| 时机 | 适用场景 |
|---|---|
| 当被创建时 | 初始化设置 |
| 当被点击时 | 交互响应 |
| 当受到伤害时 | 战斗逻辑 |
| 当生命值变化时 | 状态更新 |
| 当接近时 | 触发事件 |
| 重复执行直到 | 周期检查 |
5.3 广播链
复杂的业务流程可以通过广播链实现:
UI 发送 "请求_XXX"
→ 地图处理并发送 "通知_YYY"
→ 相关对象响应 "通知_YYY"
→ 完成后发送 "完成_ZZZ"
→ UI 收到 "完成_ZZZ" 刷新显示6. 联机环境下的广播
6.1 联机广播的特点
在联机环境下使用广播需要注意:
| 问题 | 说明 | 解决方案 |
|---|---|---|
| 上传延迟 | 公共数据需要同步给其他玩家 | 减少连续多次写入 |
| 帧率限制 | 旧版本 UI 帧率被限制到 20 帧 | 更新到 4.52.54+ 版本 |
| 数据冲突 | 多玩家同时操作可能冲突 | 使用地图层集中处理 |
6.2 联机广播最佳实践
UI 只发请求广播
UI 脚本: 当按钮被点击时 → 发送广播 "请求_购买"地图集中处理
地图脚本: 当收到广播 "请求_购买" 时 → 在地图层检查和处理 → 处理完成后发广播通知 UIUI 收到结果后刷新
UI 脚本: 当收到广播 "购买_完成" 时 → 刷新 UI 显示
6.3 4.52.54+ 版本优化
4.52.54 版本后,每个玩家只运行自己的 UI 逻辑,显著提升了:
- 玩家人数较多的场景
- UI 界面复杂的场景
- 需要无限循环实现动画的场景
7. 广播常见问题排查
7.1 广播没效果
检查清单:
| 检查项 | 说明 |
|---|---|
| 广播名称是否一致 | 注意大小写、空格、标点符号 |
| 监听脚本是否在正确触发时机 | 需要「当收到广播时」触发时机 |
| 监听者在广播发送时是否存在 | 如果对象已销毁则不会响应 |
| 广播发送时机是否在监听者初始化之后 | 确保监听者先注册 |
7.2 广播触发顺序不对
如果多个监听者需要按顺序执行,可以:
- 使用不同的广播名称按顺序发送
- 在脚本中加入等待语句控制顺序
- 把多个响应合并到一个脚本中处理
7.3 广播太多难以维护
如果项目中广播太多,可以:
- 建立广播命名规范文档
- 使用统一的广播前缀
- 记录所有广播的用途
- 考虑是否可以用其他机制替代部分广播
8. 广播与组件的配合
8.1 自定义组件中的广播
在自定义组件中可以使用广播:
自定义组件:
属性:当前状态
当执行 "切换状态" 指令时
→ 发送广播 "状态_改变" 并携带文本 当前状态
→ 等待 0.1 秒
→ 发送广播 "状态_确认"8.2 组件事件触发广播
某些组件事件会自动触发广播:
| 组件 | 事件 | 说明 |
|---|---|---|
| 生命组件 | 当受到伤害时 | 可以发送广播通知其他系统 |
| 武器槽组件 | 当武器切换时 | 可以发送广播通知 UI 更新 |
| 可互动物体 | 当互动按钮被按下时 | 可以发送广播触发业务逻辑 |
9. 广播使用检查表
在项目中检查广播使用时,可以参考以下检查表:
| 检查项 | 说明 |
|---|---|
| ✓ 广播名称是否有语义 | 能从名称理解发生了什么事 |
| ✓ 是否解耦了发送者和监听者 | 发送者不需要知道谁响应 |
| ✓ UI 是否只发请求广播 | 业务逻辑在地图层处理 |
| ✓ 是否有广播命名规范 | 保持项目内命名风格一致 |
| ✓ 是否避免了过度使用广播 | 不是所有场景都需要广播 |
| ✓ 联机环境是否考虑了延迟 | 减少了连续多次公共数据写入 |
10. 相关页面
- 广播机制深度解析 - 广播机制的深入分析
- 广播驱动项目结构实战 - 广播驱动的架构设计
- 脚本实战架构入门 - 项目架构设计
- UI数据同步架构 - UI 与地图的数据配合
- 核心概念速查手册 - 核心概念速查
待验证问题
以下问题需要进一步验证:
| 问题 | 状态 | 验证方向 |
|---|---|---|
| 不同组件事件触发的广播是否有优先级差异 | 🔄 待验证 | 需要实际测试不同组件 |
| 广播链的深度限制 | 🔄 待验证 | 需要压测确认上限 |
| 带参数广播的参数类型限制 | 🔄 待验证 | 需官方文档确认 |
📝 说明:以上问题对日常使用影响较小,基本广播用法已稳定可靠。
后续优化方向
- [ ] 补充更多实际项目中的广播使用案例
- [ ] 添加广播与信号量的对比说明
- [ ] 完善联机广播的详细文档
