创游世界联机同步与多人游戏设计指南
一句话摘要
本文档系统介绍创游世界引擎的联机同步机制与多人游戏设计方法,涵盖同步模式选择、数据同步策略、联机UI优化、常见问题与最佳实践。
适合谁阅读
- 想设计多人联机游戏的创作者
- 遇到联机UI卡顿问题的开发者
- 需要了解联机同步机制的进阶用户
- 想学习联机游戏数据架构的设计者
你将学到什么
- 联机同步的基本原理
- 不同同步模式的适用场景
- 数据同步的层级选择
- 联机UI的优化方法
- 常见联机问题的解决方案
- 多人游戏的项目架构设计
核心结论
- 联机UI是关键性能瓶颈:4.52.54前版本每玩家设备模拟所有UI,帧率限制20帧
- 数据同步要分层:真值层/UI层分离,避免直接操作
- 广播是解耦核心:用广播替代直接调用,简化同步逻辑
- 玩家变量是持久化基础:跨会话数据必须用玩家变量
- 地图属性适合临时状态:联机临时数据可以用地图属性
背景说明
创游世界的联机系统经历了多次版本迭代,从最初的「上传并等待」模式,到4.52.54版本引入的「当前UI」机制,再到4.54.0版本的数据类型升级,联机能力在不断完善。
理解联机同步机制,是设计稳定多人游戏的前提。
1. 联机同步基础
1.1 联机同步的定义
联机同步 是指在多人游戏中,确保各玩家看到一致的游戏状态的过程。包括:
- 位置同步(玩家移动)
- 状态同步(生命值、道具等)
- UI同步(界面上显示的内容)
- 事件同步(广播、触发等)
1.2 同步模式的演进
| 版本 | 同步模式 | 特点 |
|---|---|---|
| 4.52.54前 | 玩家.当前UI | 每个设备模拟所有玩家UI,帧率限制20fps |
| 4.52.54+ | 当前UI | 每玩家只运行自己的UI逻辑,帧率恢复正常 |
| 4.54.0+ | 数据类型升级 | 支持结构体、单选值等,数据结构更丰富 |
1.3 联机UI的核心问题
问题:4.52.54前版本,联机UI卡顿严重。
原因:每个玩家的设备都会模拟所有玩家的UI逻辑,包括其他玩家的UI更新,导致性能开销巨大。
解决:4.52.54+版本引入当前UI机制,每个玩家只运行自己的UI逻辑。
2. 同步层级设计
2.1 数据层级对照
| 层级 | 作用域 | 联机行为 | 适用场景 |
|---|---|---|---|
| 局部变量 | 单脚本执行 | 不同步 | 临时计算 |
| 自身属性 | 单物体 | 不同步 | 单机物体状态 |
| 地图属性 | 地图内 | 可同步 | 地图内共享数据 |
| 系统属性 | 全游戏 | 可同步 | 全局共享数据 |
| 玩家变量 | 账号绑定 | 同步 | 玩家进度、货币 |
2.2 同步策略选择
策略1:玩家变量同步(推荐)
适用场景:需要跨会话持久化的数据。
脚本逻辑:
当玩家进入地图时
读取玩家变量 "金币"
广播 "UI_刷新_金币" 并携带数值 金币优点:数据可靠,跨会话保持 缺点:需要考虑写入频率限制
策略2:地图属性同步
适用场景:联机时需要所有玩家看到一致,但不需要跨会话保持的数据。
脚本逻辑:
当获得道具时
设置地图属性 "当前怪物击杀数" 为 地图属性 "当前怪物击杀数" + 1
广播 "UI_刷新_击杀数" 并携带数值 击杀数优点:实时同步,不需要等待 缺点:切地图后数据重置
策略3:广播驱动同步
适用场景:需要跨对象协作,但不需要持久化的数据。
脚本逻辑:
当获得道具时
发送广播 "道具_获得_玩家" 并携带文本 道具ID
--- 玩家脚本 ---
当收到广播 "道具_获得_玩家" 时
增加玩家变量 "背包" 中对应道具数量优点:解耦清晰,易于维护 缺点:需要确保广播能被所有相关对象接收
3. 联机UI优化
3.1 UI架构原则
原则1:真值与显示分离
正确做法:
UI只负责显示和接收输入
真值放在地图层或系统层
UI操作发送广播通知地图处理
地图处理后广播刷新UI原则2:每玩家只运行自己的UI
错误做法(4.52.54前):
玩家A的设备上运行所有玩家的UI逻辑
正确做法(4.52.54+):
每玩家只运行自己的UI逻辑
通过玩家变量或广播与服务器同步原则3:减少公共数据写入
错误做法:
UI中连续多次写入公共数据
正确做法:
UI只发送一次广播给地图
地图集中处理所有数据写入
广播通知所有相关UI刷新3.2 联机UI性能检查清单
- [ ] 更新到4.52.54+版本
- [ ] 确认使用
当前UI而不是玩家.当前UI - [ ] 每个玩家只运行自己的UI逻辑
- [ ] UI不直接写入公共数据,而是发送广播
- [ ] 减少UI中的等待语句
- [ ] 避免在UI中使用无限循环做动画,改用
渐变语句
3.3 联机UI典型架构
玩家对象:
├── 脚本A:初始化UI
│ 当开始时
│ 显示主界面UI
│ 广播 "刷新_货币"
│
├── 脚本B:刷新货币显示
│ 当收到广播 "刷新_货币" 时
│ 显示货币UI元素
│
├── 脚本C:处理购买
│ 当收到广播 "购买完成" 时
│ 广播 "刷新_货币"
│
UI对象:
├── 脚本A:购买按钮点击
│ 当UI点击购买按钮时
│ 发送广播 "请求_购买" 并携带文本 商品ID
│
地图对象:
├── 脚本A:处理购买请求
│ 当收到广播 "请求_购买" 时
│ 读取玩家变量 "货币"
│ 如果货币足够
│ 扣除货币
│ 给予道具
│ 发送广播 "购买完成"4. 多人游戏设计
4.1 玩家数据设计
核心数据:
玩家变量.金币:货币数量玩家变量.经验:经验值玩家变量.等级:角色等级玩家变量.背包:道具列表玩家变量.装备:装备列表玩家变量.任务进度:任务完成状态
同步策略:
玩家数据同步流程:
1. 玩家进入地图时,从玩家变量读取数据
2. 广播给UI刷新显示
3. 玩家操作时,更新玩家变量
4. 需要同步时,发送广播通知其他相关UI4.2 怪物/ NPC数据设计
服务器端数据(地图属性或系统属性):
地图属性.怪物列表:当前地图的怪物状态地图属性.NPC状态:NPC交互状态地图属性.机关状态:机关开启/关闭状态
客户端表现(UI):
- UI只显示服务器端数据的当前状态
- 不在UI中缓存数据副本
4.3 位置同步
简单同步(适合普通移动):
- 使用内置的物理同步
- 角色组件自带基本的位置同步
精确同步(适合射击、格斗):
- 自定义同步协议
- 定期广播位置更新
- 使用插值平滑显示
位置同步脚本:
当开始时
创建定时器 "同步位置"
无限循环 {
每0.1秒执行
发送广播 "同步_位置" 并携带数值 自身X坐标
发送广播 "同步_位置" 并携带数值 自身Y坐标
}5. 常见问题与解决
Q1:联机时UI很卡怎么办?
A:
- 更新到4.52.54+版本
- 确认使用
当前UI而不是玩家.当前UI - 优化UI广播模式,减少公共数据写入
- 避免在UI中使用无限循环做动画
Q2:玩家数据不同步怎么办?
A:
- 确认数据存储在玩家变量而不是局部变量
- 检查写入时机,确保在联机同步范围内
- 使用广播确认数据已更新
- 检查是否有版本兼容问题
Q3:广播在联机时无效怎么办?
A:
- 确认广播名称一致
- 确认监听脚本在正确的触发时机下
- 确认联机模式下广播下沉设置
- 考虑使用玩家变量或地图属性替代广播
Q4:切换地图后数据丢失怎么办?
A:
- 确认数据存储在玩家变量而不是地图属性
- 玩家变量是跨会话持久化的
- 地图属性在切地图时会重置
Q5:如何避免数据冲突?
A:
- 使用中央处理器模式(地图统一处理数据)
- 避免多个客户端同时写入同一数据
- 使用事务性操作确保数据一致性
- 考虑使用版本号或时间戳检测冲突
6. 联机游戏架构模板
项目结构:
├── 地图
│ ├── 主场景
│ ├── 战斗场景
│ └── 商店场景
├── 管理器
│ ├── 数据管理器(处理所有数据写入)
│ ├── 同步管理器(协调联机同步)
│ └── 事件管理器(分发广播事件)
└── 脚本规范
├── 玩家脚本(只处理玩家输入和显示)
├── 地图脚本(处理真值和业务逻辑)
└── UI脚本(处理显示和交互请求)相关页面
- 创游世界联机系统完全指南 - 联机系统完整指南
- 创游世界联机系统入门 - 联机入门
- 创游世界数据存储选择指南 - 数据存储选择
- 创游世界广播机制完全指南 - 广播机制
- 创游世界UI界面设计系统指南 - UI设计
待验证问题
[待验证]地图属性的具体联机同步机制[待验证]广播在联机模式下的下沉设置[待验证]玩家变量的写入频率限制[待验证]不同版本联机能力的具体差异
后续优化方向
- 补充具体同步脚本示例
- 添加更多联机游戏类型的架构案例
- 完善调试工具的使用说明
- 增加联机性能测试方法
