12 KiB
Unity UI 降 DC 优化包(可移植归档)
归档时间:2026-09-10 | 来源工程:T5(
d:\Project\T5)、T11(d:\Project\T11) 一句话:四条互相独立的降 DrawCall 路线 + 配套巡检工具 + 排查方法论,全部来自 T5/T11 实战并已验证生效,业务代码零改动。
一、这个包解决什么问题
Unity UI 的 DrawCall 高,通常是四个不同原因叠加。本包按功能分成四个目录,可以单独取用,互不依赖:
| 路线 | 病因 | 药方 | 目录 |
|---|---|---|---|
| ① UIEffect 材质共享 | Coffee.UIEffect 5.x 给每个组件建独立材质实例(缓存 key 用实例唯一的 effectId)→ 100 个同配置图标 = 100 个材质 = 完全无法合批 |
把缓存 key 换成配置内容指纹 configId → N 个同配置特效共享 1 个材质 → 可被 UGUI 动态合批 |
01_ |
| ② 全屏面板遮挡 | 全屏界面打开时,被完全盖住的下层界面照样提交 DC(GPU 白画一遍) | 挂 FullScreenCover 组件 → 打开时把下层 SetActive(false),关闭时自动恢复 |
02_ |
| ③ 渲染设置与资源清理 | URP Renderer 里 SSAO 等 Feature 在 2D/UI 场景纯属浪费;超大散图撑包体 | 关掉 SSAO(省 4 个 DC)、Skybox 改纯色、删无用大图 | 03_ |
| ④ 巡检工具 | 靠人眼在几百个 prefab 里找问题不现实 | Prefab/图片/图集静态扫描 + 界面性能巡检(含相似图 LSH、dHash) | 04_ |
T5 实测总收益:大厅整帧批次数 约 100 → 35;等级礼包面板 101 → 3040 量级(①的贡献,具体取决于同面板内同配置特效数量)。
另外 05_ 是排查方法论(Frame Debugger 看图、编辑器 FPS 乱跳、Profiler 三步法),99_ 是原始提交全量 diff(仅供对照,不建议直接 apply,原因见第五章)。
二、目录结构与文件清单
★ = 必读/推荐入口。每个功能目录内都是「补丁 + 成品源码 + 说明文档」三件套,可单独取用。
DC优化归档/
├── README.md ← 本文件(总入口)
│
├── 01_UIEffect材质共享降DC/ ← 路线①:同配置特效共享材质
│ ├── 移植与验证手册.md ★必读 8 章:前提核对/安装/验证/回滚/坑
│ ├── uieffect_configId.patch ★推荐 git 标准补丁(2 文件 +126 -2)
│ ├── UIEffectContext.cs 打完补丁的成品源码(兜底覆盖用)
│ ├── UIEffectBase.cs 打完补丁的成品源码(兜底覆盖用)
│ └── UIEffect降DC改动总结.md T11 原始技术文档(方案选型 + 指纹算法)
│
├── 02_全屏面板遮挡省DC/ ← 路线②:盖住的界面不再出 DC
│ ├── FullScreenCover_使用方法与避坑.md ★必读 9 章:配置/原理/移植/★2 个真实陷阱/排查
│ ├── fullscreen_cover_mechanism.patch ★推荐 git 标准补丁(4 文件 +474)
│ ├── FullScreenCover.cs 组件本体(17 行,挂预制体根节点)
│ ├── IPanelBase.cs 接口(新增 5 个成员)
│ ├── PanelBase.cs 核心实现(遮挡/恢复全部逻辑)
│ └── FullScreenCoverTool.cs 编辑器工具(Tools/UI/全屏面板遮挡工具)
│
├── 03_渲染设置与资源清理/ ← 路线③:渲染管线开销
│ └── urp_关闭SSAO.patch URP Renderer 的 SSAO m_Active 1→0(省 4 DC)
│
├── 04_性能与图片巡检工具/ ← 路线④:批量找问题
│ ├── UIPrefabCheck_能力与优化清单.md ★必读 7 个标签页能力表 + 4 个缺口 + 分级优化方案
│ └── UIPrefabCheck.cs 工具源码副本(1434 行,只读归档)
│
├── 05_排查方法论/
│ └── DC与帧率排查经验.md Frame Debugger 看图/编辑器 FPS 乱跳/Profiler 三步法
│
└── 99_原始提交备查/ ← 仅供对照,不建议直接 apply
├── T5_c61b9012_UIEffect补丁提交.patch 路线① 在 T5 的原始提交(混入了 prefab 改动)
└── T5_cdbbca4b_DC战役总提交.patch 路线②③ 的总提交(905 KB,含删 30MB 大图)
各路线的动手前必读
| 路线 | 必读文档 | 核心前提 |
|---|---|---|
| ① UIEffect | 01_/移植与验证手册.md |
UIEffect 必须是本地源码包(file: 引用),不能是 PackageCache 只读包 |
| ② 全屏遮挡 | 02_/FullScreenCover_使用方法与避坑.md |
必须用 MFrame 的 PanelBase<V> + PanelMgr + UILayerIdx 体系;第七章两个陷阱务必看 |
| ③ 渲染设置 | 无(补丁即说明) | URP;2D/UI 场景才有意义 |
| ④ 巡检工具 | 04_/UIPrefabCheck_能力与优化清单.md |
静态扫描 6 页删 using MFrame; 即可搬走;性能巡检页强绑 T5 框架需重写 |
三、快速开始
四条路线互相独立,按需取用。建议顺序:③(改一个数字,风险最低)→ ② → ① → ④(工具,最后上)。
路线③ 渲染设置(最简单,先看这个)
cd <目标工程 git 根目录>
git apply --3way "<归档路径>\03_渲染设置与资源清理\urp_关闭SSAO.patch"
只改一个 m_Active: 1 → 0。也可以在 Unity 里手动做:选中 URP Renderer 资产 → 找到 SSAO Feature → 取消勾选。2D/UI 场景关掉无视觉损失。
路线② 全屏遮挡
cd <目标工程 git 根目录>
git apply --check "<归档路径>\02_全屏面板遮挡省DC\fullscreen_cover_mechanism.patch"
git apply --3way "<归档路径>\02_全屏面板遮挡省DC\fullscreen_cover_mechanism.patch"
动手前必须先读 02_/FullScreenCover_使用方法与避坑.md 第六章(前提核对)与第七章(两个真实陷阱)。编译通过后用菜单 Tools/UI/全屏面板遮挡工具 逐个挂组件,一次只挂一个并立即验证。
路线① UIEffect(3 步)
前提:目标工程把 UIEffect 以本地源码包方式引入(Packages/manifest.json 里形如
"com.coffee.ui-effect": "file:../my_libs/unityLib/UIEffect-main/Packages/src")。
如果它在 Library/PackageCache/ 下(只读),先按手册第二章把它生成本地包,否则改了也白改。
# 1) 进目标工程的 git 根目录(T5 是 <项目>/T5_game)
cd <目标工程 git 根目录>
# 2) 应用补丁(--3way 允许三方合并,冲突时会在文件里留标记)
git apply --3way "<归档路径>\01_UIEffect材质共享降DC\uieffect_configId.patch"
# 3) 回 Unity 编译,打开目标面板用 Frame Debugger 看批次是否下降
apply 失败(版本不同、路径不同)就走兜底:把 01_UIEffect材质共享降DC/ 里的两个 .cs 直接覆盖到目标工程的
.../UIEffect-main/Packages/src/Runtime/ 下;再不行就照 移植与验证手册.md 第三章手工贴代码块。
路线④ 巡检工具
把 04_/UIPrefabCheck.cs 拷到目标工程 Assets/Editor/ 下即可。静态扫描 6 页可能需删 using MFrame;;性能巡检页强绑 T5 框架,详见 UIPrefabCheck_能力与优化清单.md 第五章。
四、路线① 改动核心(速览)
UIEffectBase.cs → GetModifiedMaterial(),材质缓存 key 换掉:
// 改前:effectId = 组件实例唯一 → 永不共享
var rootId = (uint)(transitionRoot != null ? transitionRoot.GetHashCode() : 0);
var hash = new Hash128((uint)baseMaterial.GetHashCode(), effectId, samplingScaleId, rootId);
// 改后:configId = 配置内容指纹 → 同配置共享
var configId = context.configId;
var rootId = context.useViewMatrix && transitionRoot ? (uint)transitionRoot.GetInstanceID() : 0u;
var hash = new Hash128((uint)baseMaterial.GetInstanceID(), configId, samplingScaleId, rootId);
UIEffectContext.cs,新增 121 行:configId 属性(反射遍历所有 public 序列化字段 → FNV-1a 混合 → MurmurHash3 终混雪崩),配套 Mix / HashValue / HashFields / GradientHash 与两个静态缓存 s_ConfigFields、s_FieldCache。
三个设计要点(细节见 UIEffect降DC改动总结.md):
- 反射结果静态缓存:
GetFields只在类型加载时跑一次,运行时无类型发现开销,避免批量刷新时的 GC 尖峰; Gradient按内容哈希:不同实例、内容相同的渐变得到相同指纹(否则按引用哈希会白拆批次);rootId仅在需要视图矩阵时参与(transition / gradation / detail / shiny),普通灰度不受 root 影响,共享范围更大。
五、来源与可追溯性
| 项目 | 提交 | 路线 | 说明 |
|---|---|---|---|
| T11 | fa5f0cdb 降低DC的操作(2026-08-26) |
① | 首次实现,产出 UIEffect降DC改动总结.md |
| T5 | cdbbca4b 提交DC优化 |
②③ | FullScreenCover 整套机制 + 关 SSAO + 删 30MB 无用大图 |
| T5 | c61b9012 优化DC(2026-09-08) |
① | 从 T11 移植到 T5,验证生效(DC 确认下降) |
| T5 | d9fc47e0 debug |
② | 因副本异常把 UI_RaidSelectPanel 的 FullScreenCover 摘掉(详见 02_ 文档第七章) |
为何
99_原始提交备查/里的补丁不建议直接 apply:两个提交都是“搭车提交”,路线混在一起:
c61b9012除了路线① 的 2 个源码文件,还捎带了 7 个面板 prefab 的isKeepShowWhenCovered: 1 → 0(属路线②的配置);cdbbca4b除了路线②③,还含删图、prefab 改动等共 905 KB diff。所以各功能目录里提供的是拆分后的纯净补丁(
uieffect_configId.patch、fullscreen_cover_mechanism.patch、urp_关闭SSAO.patch), 原始提交只用于事后对照“T5 当时到底改了什么”。
六、本包缺什么(诚实说明)
- ⚠ 路线② 有一个已知隐患未修,随包一起交付:
PanelBase.RestorePanelsHiddenByMe()只看“是否被遮挡隐藏”, 不看“是否已被业务 Close”,导致已关闭的面板可能被SetActive(true)复活。T5 副本异常就是这么来的, 当时的处置是把 RaidSelectPanel 的组件摘掉(保守做法),框架层的 4 行守卫至今未实施(已核实:PanelBase 全文搜_closed/isClosed零命中)。 归档的源码是 T5 当前真实状态(含隐患),修复代码已写在02_/FullScreenCover_使用方法与避坑.md第七章陷阱一,移植时建议一并补上。 - UI DC 体检工具(
UIDCProbeTool.cs)没有归档进来:该工具在 T5 里按需求删除时从未提交进 git, 会话缓存中也没有源码副本,已不可恢复。它当时的能力是:运行时按 Canvas 采集真实批次 + 材质分组模式 (按材质/纹理 hash 归组,定位"谁在拆批次")。如果新项目需要,可按05_/DC与帧率排查经验.md的思路重建, 或直接用 Unity 自带的 Frame Debugger(多数场景够用)。 更推荐的替代路线:04_/UIPrefabCheck_能力与优化清单.md的 A1 + A2 两项——给界面性能巡检加 DC/批次指标、再给静态扫描加一页"合批体检",即可覆盖 UIDCProbeTool 的核心价值,而且静态分析可批量、 可导表、不需要 Play Mode,比原来那个运行时版本更好用。 ShaderVariantRegistry.cs的 Profiler.EndSample 配对修复没有归档:T11 文档提到过这个改动, 但 T5 当前插件版本(5.11.3)里该文件的采样配对本身已是正确的,未做修改,因此无补丁可归档。 若目标工程控制台出现Non-matching Profiler.EndSample,按01_/移植与验证手册.md第四章处理。- 路线③ 只归档了 SSAO 一项:当时还做了 Skybox 改纯色、删三张超大图(map.png 30MB / bg.png ×2 各 ~2.5MB),
这些属于具体工程的美术决策,不具可移植性,只在
99_/T5_cdbbca4b里能看到完整 diff。