第 7 章 · 网络 Debug 面板与最小测试矩阵
第 1-6 章建立了一整套概念:四象限状态、四种通道、Owner / Master、生命周期、迟入恢复、网络预算。这些概念能不能在自己的项目里跑通,必须能动手测。这一章给一份「最小测试矩阵」,后面每一章写完同步代码,都按这份矩阵跑一遍。
启用网络调试 GUI
Section titled “启用网络调试 GUI”VRChat 客户端默认不显示网络调试面板。要打开:
桌面端启动参数:
--enable-debug-gui通过 Steam 启动:右键 VRChat → 属性 → 启动选项,加上这一行。
进入实例后,按住 Right Shift + 反引号 `,再按数字键 1-9 打开对应面板。
第一部反复用到的三个:
| 面板 | 显示内容 |
|---|---|
| Debug View 6 | 列出所有 networked object:Owner、size、BPS、ping |
| Debug View 7 | 同 6,按「网络影响」排序 |
| Debug View 8 | 在所有 synced object 上叠加面板:Owner ID、ping、收包质量百分比、held / sleeping 状态 |
第 6 章讲的字节预算,跑到 Debug View 6 里能看到每个对象实际占用的 BPS。理论估算和实测对比,是排查同步问题的第一步。
多客户端 Build & Test
Section titled “多客户端 Build & Test”VRChat SDK 的 Control Panel 里有个 Build & Test 按钮。它会把当前世界打包成本地客户端可加载的格式,然后启动 VRChat 直接加载。
要测同步必须开两个客户端。两种方法:
方法一:同一台机器开两个客户端。 在 SDK Builder 面板把 Number of Clients 设为 2,再点 Build & Test。Unity 会启动两个 VRChat 客户端,它们会进入同一个本地测试实例。
方法二:Build & Test 配合 Editor Play Mode 辅助观察。 Editor Play Mode 或 ClientSim 适合看本地逻辑、Inspector 和 Console,但不能替代真实客户端的网络同步测试。涉及同步变量、Custom Network Event、Master / Owner 行为时,以 Build & Test 启动的真实 VRChat Client 为准。
几件事要先知道:
- Editor / ClientSim 里的
Networking.LocalPlayer、实例创建者判断、网络时序都不能完整代表真客户端,涉及实例创建者判断时必须用 Build & Test 的真客户端。 - 不要用 Editor Play Mode 的结果判断跨客户端送达。官方 Build & Test 文档明确把 Synced Variables、Custom Network Events、多玩家行为归到真实客户端测试场景。
- 多客户端共用一台机器麦克风会互相串音,测语音相关功能要至少两台机器。
最小测试矩阵
Section titled “最小测试矩阵”写完一段新的同步代码,跑这五个场景。每章后续的「踩坑预警」基本都对应矩阵里某一行。
测试 1 · Owner 端 → 远端基本同步
Section titled “测试 1 · Owner 端 → 远端基本同步”最基础的:Owner 改字段,远端能不能看到。
步骤:
- 客户端 A 触发改动(按按钮、调滑块等)。
- 客户端 B 看是否在 1 秒内同步到。
- 打开 Debug View 8,看对象上是否显示「P=ping、Q=100%」之类的健康指示。
通不过就回头查这几项:
- UdonBehaviour 的 Sync Method 是不是 None。
[UdonSynced]标记有没有漏。- 改字段前是不是 Owner。
- Manual 模式下有没有忘记
RequestSerialization。
测试 2 · 迟入恢复
Section titled “测试 2 · 迟入恢复”第 5 章的核心场景。
步骤:
- 客户端 A 进入实例,触发若干状态变更(按几次按钮、推怪几下)。
- 不要让 A 退出,让客户端 B 后进来。
- 检查 B 看到的状态:UI、灯光、敌人位置、波次数字,是否都和 A 一致。
- 检查 B 的 Console(如果是 Editor),有没有「
OnDeserialization触发了多少次」的日志。
通不过就回头查这几项:
- 这个状态是不是档①但用了网络事件实现。
OnDeserialization里有没有依赖未同步的字段。[UdonSynced]字段的初值有没有给合理默认值。
测试 3 · Owner 离开
Section titled “测试 3 · Owner 离开”第 3 章的场景。
步骤:
- A 和 B 一起进入实例,A 是初始 Master 兼默认 Owner。
- A 触发若干同步变更,B 端看到正确状态。
- A 强制退出(关掉 A 的客户端,正常从 VRChat 主菜单退出即可,避免 ALT-F4 跳过某些清理回调)。
- B 这边观察:
OnPlayerLeft是否触发?- 之前 Owner 是 A 的对象,现在 Owner 自动转给了谁?(应该是 B,因为 B 此时是新 Master)
- B 的
OnOwnershipTransferred(player)是否触发? - 同步状态有没有被卡在中间值?
通不过的典型表现:AI 怪不动了,多半是 AI 状态机依赖 Master 而非 Owner;分数倒退,多半是新 Owner 接管时同步字段被默认值覆盖。
测试 4 · Owner 主动转移
Section titled “测试 4 · Owner 主动转移”Networking.SetOwner(Networking.LocalPlayer, gameObject);步骤:
- A 是当前 Owner。
- B 触发抢权(按一个 Pickup、按一个按钮等)。
- 两边都应该收到
OnOwnershipTransferred(player == B)。 - B 立刻改字段,A 端能否看到。
- A 立刻再改字段,看会不会被同步出去(不应该,B 才是新 Owner)。
测试 5 · 网络拥塞下的日志
Section titled “测试 5 · 网络拥塞下的日志”人为拉一下带宽,看代码有没有崩。
步骤:
- 在某个同步对象上接一个测试按钮,让它在 1 秒内连续 100 次
RequestSerialization,每次写一个不同字段。 - 触发后看:
OnPostSerialization报告success == false的次数。Networking.IsClogged是否进入true状态。- 远端 B 接收到的最终值是否是最后一次提交的值。
- 测试结束,确认正常逻辑(按钮、UI)能恢复。
通过的标准是「拥塞期间逻辑变慢但不崩」。
一份测试模板
Section titled “一份测试模板”把这份模板放进每个同步对象的注释里,写完每章功能填一遍。
=== Sync Test Matrix · GameState ===[ ] Test 1: Owner change → remote sees within 1s[ ] Test 2: Late joiner gets current state correctly[ ] Test 3: Owner leaves → ownership transfers, no value drift[ ] Test 4: SetOwner → both sides receive OnOwnershipTransferred[ ] Test 5: 100x RequestSerialization in 1s → no crash, logical state intact
Notes:-第 1 章拆状态时给状态分类是案头作业。这份测试矩阵是落地后的实际验证,两边对得上才算同步设计走通了。
把第 2 章实现 C 的同步按钮加进项目,按照测试矩阵跑五个测试。每个测试结果写一行:通过 / 不通过 / 不确定。
不通过和不确定的项就是后续章节要回头处理的。
进阶:在按钮上加一个「连续 50 次按下」的测试按钮(自动用 SendCustomEventDelayedFrames 触发),看测试 5 的拥塞表现。比较 Continuous 和 Manual 两种模式下的差异。
第一部回头看
Section titled “第一部回头看”到这里第一部七章的具体内容讲完了。第 1 章把状态拆成四象限:先拆状态,再选通道。第 2 章给出四种通道(Local / Event / Variable / ObjectSync),默认按 A → D 顺序选,能停就停。第 3 章说清楚 Owner、Master、Local Player 三个判断回答的不是同一个问题。第 4 章画出手动同步的生命周期:请求 → OnPreSerialization → 发送 → OnPostSerialization,远端 OnVariableChanged / OnDeserialization。第 5 章说迟入只复制状态、不重放事件,按四档分类。第 6 章给出三个网络数字(200B / 49KB / 约 11 KB/s),「能塞进去」和「持续发得起」是两件事。第 7 章给出测试矩阵五项,每写完同步代码跑一遍。
第一部理解章会把这七章揉成一个核心心智模型:「同步不是广播,是状态复制」。
第二部开始写真实的对象架构:玩家进入房间时系统给他什么、VRCPlayerObject 的位置、GameState 的拓扑设计。
- VRChat Creator Docs · Build & Test — Build & Test 启动流程的官方文档。
- VRChat Creator Docs · World Debug Views — Debug View 6/7/8 详细说明。
- 社区文档 · VRCD · Networking 调试 — 中文整理的调试经验。
- 附录 · 术语表 — 第一部所有术语的客观定义索引。