🛠️
完成目标:主机创建房间并得到加入码,客户端加入后由 NGO 建立连接,主机统一加载游戏场景,双方可以安全离开并回到主菜单。

项目结构

建议把职责拆开:
  • UI:读取输入、显示加载和错误状态
  • MultiplayerFlow:编排 UGS、Session 和离开流程
  • NGO NetworkBehaviour:同步具体玩法
  • NetworkSceneManager:由服务器切换网络场景
UI 不应直接调用 Lobby、Relay 和 NetworkManager 的多套底层接口。

1. 场景准备

创建两个场景并加入 Build Profiles:
  • MainMenu
  • Game
在 MainMenu 放置:
  • 配置了 UnityTransportNetworkManager
  • MultiplayerFlow
  • Host 按钮、Join 按钮、加入码输入框、状态文本
Player Prefab 必须有 NetworkObject,并配置到 NetworkManager

2. 完整流程控制器

3. UI 调用方式

Unity Button 不能直接显示绑定返回 Task 的方法。可以在 Presenter 中用很薄的 async void 事件入口,并在内部捕获异常:
async void 只留在 UI 事件边界;业务方法返回 Task,这样才能等待、测试和传播异常。

4. 为什么不要手动 StartHost

CreateSessionAsync(...WithRelayNetwork()) 使用默认网络处理器时,会配置 Relay 与 Unity Transport,并启动 NGO Host。JoinSessionByCodeAsync 会启动 NGO Client。
若随后又调用 NetworkManager.StartHost()StartClient(),就可能重复启动网络栈。只有实现自定义 Network Handler 时,才自行接管这些步骤。

5. 网络场景切换

联机游戏不要让每个客户端各自调用普通 SceneManager.LoadScene。由服务器调用 NGO 的 NetworkSceneManager.LoadScene,客户端才会按同一网络流程加载场景并同步 NetworkObject。
开始按钮还应验证:
  • 当前调用方是 Server / Host
  • 所有玩家已准备
  • Session 未锁定或处于正确阶段
  • 目标场景已加入 Build Profiles

6. 状态机比布尔值更稳

示例用 IsBusy 保持简洁。生产项目建议建立明确状态:
每个 UI 控件根据状态决定是否可用,能避免“正在加入时再次创建房间”之类的竞态。

7. 断线和恢复

至少处理三类情况:
  • 主动离开:调用 ActiveSession.LeaveAsync()
  • 网络断开但仍是成员:查询已加入 Session,并按官方 Reconnect 流程恢复
  • Host 消失:结束当前对局,或进入完整 Host Migration 流程
不要在 OnApplicationQuit 中假设异步请求一定能完成。关键状态应在正常 UI 离开流程中提交;异常退出由后端超时和会话生命周期兜底。

8. 服务端权威边界

连接成功只代表玩家能通信。所有影响游戏结果的操作仍应由服务器验证:
  • 移动速度和位置变化
  • 攻击冷却、弹药和命中
  • 道具拾取距离
  • 金币、经验和胜负
客户端发送意图,服务器修改 NetworkVariable 或生成 NetworkObject。Relay 不会替你做这些验证。

9. 测试矩阵

功能

  • Host 创建并显示加入码
  • Client 加入后生成两个 PlayerObject
  • 只有所有者能控制自己的对象
  • Host 统一加载 Game 场景
  • Client 离开后成员和对象被清理

错误

  • 空加入码、错误加入码、房间已满
  • 快速重复点击 Host / Join
  • 初始化失败、认证失败、网络断开
  • Host 在大厅和游戏中分别退出

网络

  • 100–300 ms 延迟
  • 丢包和抖动
  • 移动端切后台再恢复
  • Wi-Fi 与移动网络切换

构建

  • Editor 两实例
  • 两个独立本地 Build
  • 至少一次真实异地网络测试
  • 每个目标平台的 IL2CPP Build

10. 上线前检查

  • 认证账号可恢复,不只依赖匿名本地令牌
  • 处理 DSA 通知 API 与隐私要求
  • 核对 Lobby / Relay 费率、限流和区域
  • 日志不输出访问令牌或敏感玩家数据
  • 监控创建、加入、断线和平均会话时长
  • 为服务不可用准备明确的离线提示
  • 确认 Host 模式的作弊风险符合产品定位

系列导航

  1. 🗒️
    Unity 联机架构入门:NGO、Lobby、Relay 各自负责什么
  1. 🗒️
    NGO 入门:NetworkObject、NetworkVariable 与 RPC
  1. 🗒️
    Lobby 教程:用 Multiplayer Sessions 创建、查询和加入房间
  1. 🗒️
    Relay 教程:用 Sessions API 让 NGO 安全连接
  1. 🗒️
    完整实战:从大厅到游戏的 NGO + Lobby + Relay 流程

参考资料