跳转到内容

第 39 章 · Quest 与性能预算

约 6 分钟 难度:4 动手章

这一章解决:第七部的高风险系统放进 Quest 和多人实例后,如何先定预算、再加功能、最后按数据降级。

先看一下

一个世界在 PC 单人测试里能跑,不代表 Quest 多人房也能跑。NPC、对象池、物理对象和同步组件会把 CPU、GPU、内存、网络和 Owner 负载叠在一起。性能预算不是发布前清理,而是设计阶段的边界。

这一章会拿到什么

  • 出生点、主区域、最差视角、Quest 构建、多人测试的测量顺序
  • 渲染、脚本、网络三类预算清单
  • 第七部高风险系统的降级优先级
  • 一份上线前性能审计矩阵

依赖前面

  • 第 6 章的网络预算
  • 第 26 章的轻实时 tick
  • 第 32 章的网络拥塞降级顺序
  • 第 34 到 38 章的高风险系统边界

这是 difficulty 4 章节。只想先完成最小主项目时,可以先跳到第八部的闭环,再回来看本章的高风险系统。


优化从测量开始。先删模型、先砍脚本、先换 Shader,都可能砍错方向。VRChat 世界要按玩家实际经历的路径测。

测量点看什么
出生点第一眼可见物体、镜子、灯光、音频、视频、NPC 是否过多
主停留区玩家长时间聊天或战斗时的帧率
最差视角同时看到最多几何体、透明、粒子、灯光和同步物体的方向
Quest / Android 构建真机帧率、纹理内存、Shader 兼容、发热和卡顿
真实多人头像、拾取物、音频、视频、网络同步和 Udon 峰值

Unity 编辑器的空场景流畅,只能说明基础不坏。真正的预算边界在多人房里出现:头像加载、玩家聚集、同步物体一起动、多个 NPC 同时 tick、音频和特效同时播放。


Quest 预算里,渲染成本通常先爆。重点不是单个模型,而是同一帧里同时可见的综合成本。

成本第七部对应风险常见处理
可见几何体大量 NPC、掉落物、物理碎片分批出现,距离隐藏
材质数量每个 NPC 多套材质合并材质,复用材质
纹理内存大量敌人、UI、特效贴图控制尺寸和压缩
透明与粒子命中、爆炸、技能圈限制同时数量
灯光和阴影战斗区域动态灯优先烘焙,减少实时灯
镜子 / 视频社交区叠加战斗区限制视角和开关

高风险系统要按「同时可见」预算,而不是按资源总数预算。场景里有 100 个池化敌人并不一定坏,坏的是同一帧里 100 个都 active、都渲染、都跑动画、都同步。


脚本预算:少让对象自己每帧问问题

Section titled “脚本预算:少让对象自己每帧问问题”

UdonSharp 性能优化的基本方向是减少大量对象的 Update()。NPC、子弹、掉落物、机关都各自每帧跑逻辑,会把 CPU 切成碎片。

更稳的结构是集中调度。

private void Update()
{
if (!Networking.IsOwner(gameObject)) return;
if (phase != PHASE_INGAME) return;
double now = Networking.GetServerTimeInSeconds();
if (now - lastNpcTickTime >= npcTickInterval)
{
lastNpcTickTime = now;
TickActiveNpcBatch();
}
}

对象自身保留事件入口:受击、归还、启用、禁用。持续感知和周期检查交给 Manager 分批处理。这样能控制每帧最多处理多少对象,也方便在 Quest 上把 npcTickInterval 调大。


第 6 章已经建立网络预算:同步字段有字节和速率限制,RequestSerialization() 只是请求,网络拥塞时高频装饰事件应该先降级。第七部继续沿用这个顺序。

优先级保留可降级
1GameState 阶段、分数、波次不降级,只减少字段和发送频率
2PlayerObject 的 HP、Ready、队伍不丢失,必要时降低更新频率
3NPC 关键状态:死亡、目标、阶段只同步关键字段,不同步每帧细节
4物理对象位置减少数量,转成本地表现或低频重置
5命中特效、飘字、碎片本地播放或采样发送

Networking.IsClogged 可以作为拥塞信号之一。出现拥塞时,停止远端装饰事件,减少非关键对象同步,不要先停掉 GameState 共识字段。共识字段停了,迟入和结算都会坏。


把前几章合在一起,可以得到一张预算表。

系统预算指标降级入口
NPCactive 数量、AI tick 频率、目标搜索频率local-only、分批 tick、减少同步字段
对象池最大同时 active 数量、池耗尽次数拒绝生成、延迟生成、复用纯视觉对象
物理对象active Rigidbody 数、Owner 切换次数改成本地特效、低频状态、重置点
对象同步工具同步对象数、组件成本、维护状态回退官方组件、减少同步范围
Quest 渲染最差视角帧率、透明和粒子数量分区、隐藏、降低特效密度

这张表适合放进项目 ADR。每加一个高风险系统,就填一次:最大同时 active 是多少,Owner 是谁,迟入怎么恢复,Quest 上怎么降级。


这句话需要谨慎,但要能说出来。有些世界的核心体验就是高密度视觉、复杂物理、大量 NPC 或 PC-only Shader。如果把它强行压到 Quest,会把核心体验一起压掉。

判断方式是:Quest 降级版是否还能保留世界承诺。如果合作防守世界在 Quest 上只能保留 3 个敌人、无特效、无物理、无镜子,但核心仍然是多人防守,那可以做。如果某个世界的核心就是大规模实时物理装置,Quest 版只剩空房间,那应该明确做 PC-only,或者把 Quest 版设计成不同玩法。

重点是早判断。不要在项目末尾才发现 Quest 版跑不动。


挑一条试。

  • 给合作防守原型写一张预算表:同屏最多几个敌人、几个物理物体、几组粒子?如果 Quest 掉帧,先砍哪一项?
  • 把 NPC tick 从 0.2 秒改成 0.5 秒。玩家能感知到的变化是什么?网络和 CPU 有什么变化?
场景预期实际
1. 出生点静止 30 秒无明显掉帧,常驻特效和镜子成本可控
2. 主战斗区 4 人 + NPC帧率、Udon 时间和同步状态稳定
3. 最差视角同时可见成本在预算内,不出现明显卡顿
4. Quest 真机测试Shader、纹理、特效和脚本都能运行
5. 网络拥塞模拟装饰事件先降级,GameState 共识字段保留
6. 池耗尽生成系统拒绝或延迟,不创建额外对象
  • 能按出生点、主区域、最差视角、Quest 构建、真实多人测试性能
  • 能区分渲染预算、脚本预算和网络预算
  • 能说明为什么大量 Update() 会拖垮 Quest
  • 能按优先级保留共识字段、降级装饰反馈
  • 能给每个高风险系统写出一个降级入口