🚀 Unity 性能优化完全指南:从入门到大师的优化体系
💡 性能优化的价值 :
游戏帧率上不去,玩家体验差?
不知道从哪里开始优化,感觉无从下手?
CPU、GPU、内存、UI,到底该优先优化哪个?
工具一大堆,不知道该怎么配合使用?
这篇文章! 将建立完整的 Unity 性能优化体系,从宏观指标到具体工具,从优化策略到团队规范,助你系统掌握性能优化!
一、优化资源 1.1 官方资源
1.2 第三方资源
二、编程代码规范 2.1 基本规范
规范
说明
脚本行数
单个脚本不超过 500 行
多语言版本
不同语言版本独立 Copy 一份代码
声音配置
由策划写在 Excel 中
链式语法
使用 C# 扩展方法提升可读性
平台测试
代码必须在多平台测试通过
2.2 规范调整
💡 提示 :代码规范不是一成不变的,需要根据团队规模和代码风格进行有效调整。
三、检测工具 3.1 Unity 内置工具
工具
用途
链接
Profiler
性能分析
Unity 文档
Frame Debugger
帧调试
Unity 文档
Physics Debugger
物理调试
Unity Editor 内置
Memory Profiler
内存分析
Unity Package Manager
3.2 第三方工具
工具
平台
用途
UPR
通用
Unity 官方性能报告工具
UWA
通用
专业性能分析和优化建议
Xcode
iOS
GPU 性能和内存分析
Android Studio
Android
GPU 和内存分析
⚠️ 重要 :君子善用其器,一定要先了解工具再进行使用。
四、宏观性能指标 4.1 目标指标
指标
目标值
检测工具
FPS 帧率
>30 帧
Profiler
PSS 内存
越低越好
Xcode/Android Studio
Mono 峰值
<40MB
Profiler Memory
温度均值
越低越好
设备监控
能耗均值
越低越好
设备监控
网络上传
控制频率和大小
网络监控
网络下载
控制频率和大小
网络监控
4.2 Unity 官方建议
资源类型
建议值
Reserved Mono 峰值
<80 MB
DrawCall 峰值
<250 次
平均帧率
>25
纹理资源峰值
<50 MB
网格资源峰值
<20 MB
动画资源峰值
<15 MB
音频资源峰值
<15 MB
Tris 峰值
<200,000 面
五、微观性能关注点 5.1 分阶段关注点
模块
前期
中期
后期&上线
渲染模块
DrawCall、Triangle、Vertex
不透明、半透明、Culling
图像后处理
逻辑代码
插件、第三方库调研、bug
CPU、堆内存、调用次数
bug
UI 模块
全屏、半屏、组织结构
overdraw、重建 CPU
DrawCall
UGUI API
Canvas.BuildBatch、SendWillRenderCanvases
EventSystem.Update
RenderSubBatch
加载模块
缓存池、序列化第三方库
关注调用频率
关注耗时
加载 API
Loading.UpdatePreloading、Resources.UnloadUnusedAssets
GameObject.Instantiate
GC.Collect
资源使用
分辨率、格式、顶点数、骨骼数
数量、Mipmap、利用率、冗余
调用次数
内存占用
资源、AB 包、Mono、Lua
内存峰值、堆内存
内存泄露
粒子系统
使用指标
总体数量、active 数量
Overdraw
粒子 API
ParticleSystem.Update、SubmitVBO、Draw
ScheduleGeometryJobs
-
动画系统
数量、AC 制作、CPU
Animator.Update、Animation.Update
MeshSkinning.Update、Animator.Initialize
六、代码优化 6.1 避免产生 GC 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 foreach (var item in list) { }for (int i = 0 ; i < list.Count; i++){ var item = list[i]; } foreach (var kvp in dictionary) { }var enumerator = dictionary.GetEnumerator();while (enumerator.MoveNext()){ var element = enumerator.Current; element.Value.Update(); } enumerator.Dispose();
6.2 字符串拼接 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(); } System.Text.StringBuilder sb = new System.Text.StringBuilder(); for (int i = 0 ; i < 100 ; i++){ sb.Append(i); } string result = sb.ToString();
6.3 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 ;
6.4 集合选择
集合类型
特点
适用场景
数组
连续存储,索引快
大小固定
ArrayList
动态伸缩,非类型安全
已过时
List<T>
类型安全,动态扩展
通用集合
6.5 避免闭包 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 优化 7.1 Update 优化
技巧
说明
缓存组件
Start 中缓存 Find 结果
降低频率
隔帧执行
使用协程
替代 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 ) ; } }
7.2 协程优化 1 2 3 4 5 6 7 8 9 10 yield return null ;private WaitForSeconds waitOneSecond = new WaitForSeconds(1f );IEnumerator TestCoroutine () { yield return waitOneSecond; }
7.3 禁用优化 1 2 3 4 5 6 7 8 9 10 void OnBecameVisible (){ enabled = true ; } void OnBecameInvisible (){ enabled = false ; }
八、Component 优化 8.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 优化 9.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 ) { } }
9.2 标签比较 1 2 3 4 5 6 7 8 9 if (go.tag == "Enemy" ){ } if (go.CompareTag("Enemy" )){ }
9.3 避免 SendMessage 1 2 3 4 5 6 gameObject.SendMessage("DoSomething" ); IDoSomething handler = go.GetComponent<IDoSomething>(); handler?.DoSomething();
十、UI 资源规范 10.1 图集规范
规范
说明
最大尺寸
1024×1024
同界面同图集
减少 DrawCall
公用资源 Common
多界面复用
九宫格
减小原图大小
关闭 Mipmaps
UI 不需要
利用率
>1/3,否则合并
10.2 原图处理
处理方式
说明
全屏原图
按比例缩放最长边到 500
长条原图
拆分拼接
复用资源
使用顶点色区分品质
十一、Shader 优化 11.1 基础优化
优化项
说明
Fog { Mode Off }
关闭雾效
Alpha 剔除
剔除 Alpha=0 的像素
Fill Center
九宫格中心镂空
11.2 OverDraw 优化
优化项
说明
减少层级
减少 UI 重叠
隐藏元素
Disable 或移出裁剪区域
避免空 Image
不使用 Alpha=0 的响应区域
十二、CPU 优化 12.1 DrawCall 优化
策略
说明
合批绘制
相同图集合并
相邻同图集
避免穿插
Text 分层
避免打断合批
线框模式检测
Scene 视图 Wireframe
12.2 Mask 组件 1 2 3 4 5 var rectMask = gameObject.AddComponent<RectMask2D>();
十三、Profiler 详解 13.1 重要函数
函数
说明
优化方向
WaitForTargetFPS
Vsync 等待时间
检查 Vsync 设置
Camera.Render
相机渲染准备
优化渲染内容
Shader.Parse
Shader 解析
预加载 Shader
Reserved Total
系统申请内存
控制内存分配
GC.Collect
垃圾回收
减少内存分配
13.2 优化重点
类型
重点
检测项
GC Alloc
一次性分配 >2KB
Profiler Memory
GC Alloc
每帧分配 >20B
Profiler Memory
Time ms
占用 >5ms
Profiler CPU
ManagedHeap
移动游戏 <20MB
Profiler Memory
Device.Present
GPU 等待时间长
检查 Shader 复杂度
十四、优化检查清单 14.1 代码优化
14.2 UI 优化
14.3 资源优化
十五、参考资料
转载请注明来源 ,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1487842110@qq.com