性能优化
简介:
引擎准备数据并通知GPU的过程称为一次Draw Call。 Batch 里装的是物件顶点资料。DrawCall类似画画,一次动笔画相同颜色物体,受渲染层级影响。
(先画红后画蓝再画红肯定比先画红后画蓝耗时长)
使用不同材质球或不同Shader的物体,需要Draw Call两次。
减少Batches方法
GameObject相关
a.不修改transform修改scale大小,尺寸为1和2的物体drawcall为2
b.尺寸1与尺寸2的物体drawcall为2,尺寸1与尺寸2尺寸3的物体drawcall为2
Text相关
a. 非必要RaycastTarget不打钩
b.按钮上有文字和其他界面文字可以新建一个空层static_txt
c.如大量使用数字或相同文字的text且不得不穿插在各个图片层级下的应该考虑使用图字。如背包每个icon内都有可能穿插数字,多个相同图片只需drawcall一次。
Image相关
a.仅展示的image的RaycastTarget不打勾
b.同类图片同一图集
c.尽量减少过多链式层级分配
d.可对称的图片切到最小单元,由程序处理
e.Png边缘多余的透明区域要美术去掉
f. 没有关联任何Image的空图片层:去掉Image和CanvasRender组件
Button相关
a.尽量减少过多链式层级分配
b.按钮内需要文字参考1-b
Mask相关
a.尽量考虑使用RectMask2D组件替换(同时删除Image和CanvasRender组件)
b.去掉多余Mask和无效果Mask:比如现在有按钮上也加Mask要去掉,还有Mask无法遮挡粒子以及渲染的RawImage这样也应去掉
图集相关
a.现结构为:Dynamic(动态图片在此目录)
Func(功能型动态图集,如按钮多状态和单一界面需求的动态图片)
Icon(原则上和背包格子相关放在这里)
Static(静态图片在此目录)
Common(共用图片放在这里)
Func(界面功能性静态图集)
b.图集以目录名为tag
c.图片格式单一型:现项目大部分以png图片为主,如出现其他格式(如jpg)且较小尺寸的时候建议转成png
d.图片过大的时候考虑不添加任何图集,因单独制作管理目录作为资源加载可参考LogoSceneimages
e.游戏启动相关制作为同一图集(即使和游戏中图片重复),后期可考虑把登陆界面也包含在此范畴
f.同tag图集的图片格式和所有设置必须一致,否则每一个不同会多拆分出一个同名图集
界面关联性相关
a.界面上必须去掉所有非界面静态图片关联(如:把项目中prefab或者Image或者特效直接拖到界面的脚本上,或者把特效直接放在界面prefab上)
代码优化
1.字符串拼接,不要直接用"A"+"B",用stringbuilder或者format代替;
eg:StringBuilder sb = new StringBuilder(); sb.Append("");
string tip = string.Format("{0}",xxx);
2.字符串赋值,如果有重复和大量相同的,不要直接写在临时变量里,拉出来引用赋值;
eg: xx.IsPlayingClip("idle") ---> xx.xx.IsPlayingClip(Define.Idle);
3.尽量不要new对象,如果需要重复用到的,封装起来缓存着循环用;
eg: Info a = new Info();
a.x = x;
a.xx = xx;
转换为:Info a = Mgr.GetInfo();
a.x = x;
a.xx = xx;
4.赋值操作时,如果已有静态变量,尽量用静态变量;
eg: xxx = ""; 或者 xxx == ""; ---> xxx = string.empty;xxx == string.empty;
Vector3 vec = new vector(0,0,0) ---> Vector3 vec = vector.zero;
5.循环语句,尽量把可以提出来的执行语句提出来;
eg:for(int i = 0, i < a.count, i++) {} ---> int count = a.count; for(int i = 0, i < count, i++){}
6. GetComponent 后的东西尽量缓存,不要每次GetComponent;
eg:void Update() {Component xx = GameObject.GetComponent<Component >(); xx.Fun();} ---> Component xx = null; void Update() {if(xx == null) xx = GameObject.GetComponent<Component >(); xx.Fun();}
7. 少用协程StartCoroutine,用Update或者TimersManager代替;
8. 尽量采用有封装好的静态方法的api;
eg: A.tag == "xxx" ---> A.CompareTag("xxx");
A == xxx ---> A.Equals(xxx);
9. 不要在Update中new 对象或者创建对象;
10.协程中 yield return 0 ---> yield return null;
11.做界面时不需要的RayCast勾去掉
12.foreach 尽量 换成 for (不管unity 版本有没有优化掉)
13.尽量不要用SendMessage 来派发事件,用监听回调的方式来做;
14.继承Object的对象,在不用的时候需要置null;
15.代码模块尽量拆的散一点,一方面方面查阅,一方面为之后的热更的便捷做准备;