Unity 代码优化实战 - 从规范到 Profiler 全栈指南
涵盖代码规范、GC 优化、闭包处理、组件优化、UI 规范、Shader/CPU 优化及 Profiler 分析的完整优化指南。
一、编程代码规范 1.1 基本规范
规范
说明
脚本行数
单个脚本不超过 500 行
多语言版本
不同语言版本独立 Copy 一份代码
声音配置
由策划写在 Excel 中
链式语法
使用 C# 扩展方法提升可读性
平台测试
代码必须在多平台测试通过
1.2 扩展方法示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class WWWFormEx { private WWWForm form = new WWWForm(); public WWWFormEx AddField (string name, string value ) { form.AddField(name, value ); return this ; } public WWWFormEx AddBinary (string name, byte [] data ) { form.AddBinaryData(name, data); return this ; } } WWWForm form = new WWWFormEx() .AddField("username" , "player" ) .AddField("password" , "123456" ) .AddBinary("avatar" , avatarData);
二、代码控制与 GC 优化 2.1 避免产生 GC
写法
GC 产生
说明
foreach
✅ 产生
每次 foreach 产生枚举器
for 循环
❌ 无
使用索引直接访问
字典遍历
✅ 产生
需使用枚举器优化
字符串拼接
✅ 产生
超过 10 次需用 StringBuilder
2.2 代码优化示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 foreach (var item in list){ item.Update(); } for (int i = 0 ; i < list.Count; i++){ list[i].Update(); } foreach (var kvp in dictionary){ kvp.Value.Update(); } var enumerator = dictionary.GetEnumerator();while (enumerator.MoveNext()){ var element = enumerator.Current; element.Value.Update(); } enumerator.Dispose();
2.3 字符串拼接优化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 string result = "Hello" + " " + "World" ; for (int i = 0 ; i < 100 ; i++){ result += i.ToString(); } StringBuilder sb = new StringBuilder(); for (int i = 0 ; i < 100 ; i++){ sb.Append(i); } string result = sb.ToString();
2.4 Struct vs Class
特性
Struct
Class
内存分配
栈
堆
GC 影响
无
有
适用场景
轻量数据
复杂对象、抽象层次
1 2 3 4 5 6 7 8 9 10 11 public struct Point{ public float x; public float y; } Point p = new Point(); p.x = 10 ;
2.5 集合选择
集合类型
特点
适用场景
数组
连续存储,索引快
大小固定
ArrayList
动态伸缩,非类型安全
已过时
List<T>
类型安全,动态扩展
通用集合
2.6 其他注意事项
❌ 不要把枚举当字典的 TKey 使用
❌ 不要把枚举转成 string 使用
三、闭包与委托 3.1 变量作用域
类型
作用域
成员变量
作用于整个类
局部变量
作用于函数内
次局部变量
作用于函数局部片段
3.2 委托与闭包 1 2 3 4 5 6 7 8 9 10 11 12 闭包本质: ┌─────────────────────────────────────┐ │ 1. 代码块维护创建时的执行上下文 │ │ → 即使父方法执行完仍可访问变量 │ │ │ │ 2. 闭包关闭的是变量,不是值 │ │ → Closures close over variables │ │ → not over values │ │ │ │ 3. 闭包引用外部变量会生成新类 │ │ → 频繁调用时避免使用闭包 │ └─────────────────────────────────────┘
3.3 闭包优化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 for (int i = 0 ; i < 10 ; i++){ StartCoroutine(() => DoSomething(i)); } for (int i = 0 ; i < 10 ; i++){ StartCoroutine(DoSomethingCoroutine(i)); } IEnumerator DoSomethingCoroutine (int value ) { }
四、MonoBehaviour 优化 4.1 基本优化
技巧
说明
删除空函数
没有事件处理的空函数应删除
缓存组件
Start 中缓存 Find 结果
降低频率
隔帧执行
使用协程
替代 Update
禁用不可见
OnBecameInvisible 设置 enabled = false
4.2 Update 优化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void Update (){ if (Time.frameCount % 6 == 0 ) { DoSomething(); } } void Start (){ InvokeRepeating("DoSomething" , 0.5f , 1.0f ); } IEnumerator Start () { while (true ) { DoSomething(); yield return new WaitForSeconds (1.0f ) ; } }
4.3 协程优化 1 2 3 4 5 6 7 8 9 10 yield return null ;private WaitForSeconds waitOneSecond = new WaitForSeconds(1f );IEnumerator TestCoroutine () { yield return waitOneSecond; }
五、Component 优化 5.1 使用内建值 1 2 3 4 5 6 7 transform.position = new Vector3(0 , 0 , 0 ); transform.position = Vector3.zero; transform.localScale = Vector3.one; transform.localRotation = Quaternion.identity;
六、GameObject 优化 6.1 缓存组件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 void Update (){ var render = GetComponent<Renderer>(); } private Renderer cachedRenderer;void Start (){ cachedRenderer = GetComponent<Renderer>(); } void Update (){ if (cachedRenderer != null ) { } }
6.2 标签比较 1 2 3 4 5 6 7 8 9 if (go.tag == "Enemy" ){ } if (go.CompareTag("Enemy" )){ }
6.3 避免 SendMessage 1 2 3 4 5 6 gameObject.SendMessage("DoSomething" ); IDoSomething handler = go.GetComponent<IDoSomething>(); handler?.DoSomething();
七、NGUI vs UGPU 性能对比
特性
NGUI
UGUI
合批位置
主线程 UIPanel.LateUpdate()
子线程 Canvas.BuildBatch()
网格生成
上层创建 Vertex List
底层 C++ 代码实现
堆内存管理
频繁分配
更好的 GC 表现
八、UI 资源规范(内存优化) 8.1 图集规范
规范
说明
最大尺寸
1024×1024
同界面同图集
减少 DrawCall
公用资源
放 Common 重复利用
九宫格
减小原图大小
关闭 Mipmaps
UI 不需要
8.2 原图处理
处理方式
说明
全屏原图
按比例缩放最长边到 500
长条原图
拆分拼接(如 1000×100 → 两个 500×100)
图集利用率
>1/3,否则合并
复用资源
使用顶点色区分品质
8.3 颜色复用示例 1 2 3 4 5 6 7 8 9 10 Image qualityBG_Blue; Image qualityBG_Green; Image qualityBG_Yellow; Image qualityBG; qualityBG.color = Color.blue; qualityBG.color = Color.green;
九、GPU 优化 9.1 Shader 优化
优化项
说明
Fog { Mode Off }
关闭雾效
Alpha 剔除
剔除 Alpha=0 的像素,减少 OverDraw
Fill Center
九宫格中心镂空
9.2 OverDraw 优化
策略
说明
减少层级
减少 UI 重叠
隐藏元素
Disable 或移出裁剪区域
避免空 Image
不使用 Alpha=0 的响应区域
十、CPU 优化 10.1 DrawCall 优化
策略
说明
合批绘制
相同图集合并
相邻同图集
避免穿插
Text 分层
避免打断合批
线框模式检测
Scene 视图 Wireframe
10.2 Mask 组件 1 2 3 4 5 var rectMask = gameObject.AddComponent<RectMask2D>();
十一、Profiler 详解 11.1 重要函数
函数
说明
优化方向
WaitForTargetFPS
Vsync 等待时间
检查 Vsync 设置
Camera.Render
相机渲染准备
优化渲染内容
Shader.Parse
Shader 解析
预加载 Shader
Reserved Total
系统申请内存
控制内存分配
GC.Collect
垃圾回收
减少内存分配
11.2 优化重点
类型
重点
检测项
GC Alloc
一次性分配 >2KB
Profiler Memory
GC Alloc
每帧分配 >20B
Profiler Memory
Time ms
占用 >5ms
Profiler CPU
ManagedHeap
移动游戏 <20MB
Profiler Memory
Device.Present
GPU 等待时间长
检查 Shader 复杂度
11.3 常见性能热点
函数
原因
解决方案
Canvas.SendWillRenderCanvases
UI 重建
减少 RectTransform 变化
Canvas.BuildBatch
合批开销
合理规划图集
Debug.Log
产生堆栈
发布版本屏蔽
StackTraceUtility
堆栈追踪
减少 Debug 调用
十二、优化检查清单 12.1 代码优化
12.2 UI 优化
12.3 资源优化
十三、参考资料
转载请注明来源 ,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1487842110@qq.com