【Unity】NGUI优化

NGUI优化从以下入手:资源,贴图,内存,GameObject,UI(DrawCall)。

资源优化
》资源分离打包与加载;
资源分离打包与加载是最有效的减小安装包体积与运行时内存占用的手段。一般只分离字体和贴图这种体积较大的公用资源。可以用AssetDatabase.GetDependencies得知一份资源使用了哪些其它资源。
》界面的延迟加载和定时卸载策略;

贴图优化
》贴图透明通道分离,压缩格式设为ETC/PVRTC;
安卓上硬件支持最广泛的格式是ETC,苹果上则是PVRTC。因此我们将每张原始贴图的透明通道都分离了出来,写进另一张贴图的红色通道里。这两张贴图都采用ETC/PVRTC压缩。渲染的时候,将两张贴图都送进显存。同时我们修改了NGUI的shader,在渲染时将第二张贴图的红色通道写到第一张贴图的透明通道里,恢复原来的颜色。
》关闭贴图的读写选项;
》整理图集;
整理图集的主要目的是节省运行时内存(虽然有时也能起到合并DrawCall的作用)。
1)在界面设计上,尽量让美术将控件设计为可以做九宫格拉伸,即UISprite的类型为Sliced。
2)同样是在界面设计上,尽量让美术将图案设计成对称的形式。GameObject数量的增多有时也会显著占用更多内存。因此一般只对尺寸较大的图案采用这个方法。
3)确保不要让不必要的贴图素材驻留内存,更不要在渲染时将无关的贴图素材送进显存。不过,如果两个界面之间存在大量相同的素材,那么这两个界面就可以共用同一张图集。另外,数量庞大的图标资源(如物品图标)不要做在图集里,而应该采用UITexture。
4)减少图集中的空白地方。
有时一张1024x1024的图集中,素材所占的面积还没超过一半,这时可以考虑将这张图集切成两张512x512的图集。
》降低贴图素材分辨率;

NGUI内存优化
NGUI的Texture和Sprite释放;切换场景后第一时间调用 Resources.UnloadUnusedAssets () 释放掉。
但是如果脚本程序用到NGUI的组建的时候,比如直接拖到脚本上的物体,或者Find的物体等,只要引用NGUI的组建,它就会加到内存中,切换场景也不会释放,Resources.UnloadUnusedAssets ();也不会释放,你要结束的时候删除这些引用,就会释放掉了;

GameObject优化
》减少场景中的GameObject数量;
GameObject身上还挂载了不少脚本,每个GameObject中的每个脚本都要实例化,又是一比不菲的内存占用。因此后来我们规定场景中的GameObject数量不得超过1万,并且将GameObject数量列为每周版本的性能监测指标。
避免频繁调用GameObject.SetActive
让对象一直保持激活状态(activeInHierarchy为true),而原来的SetActive(false)改为将对象移到屏幕外,SetActive(true)改为将对象移回屏幕内。这样性能就好多了。

UI界面优化(Drawcall)
》根据各个UI控件的设计安放Panel,隔开DrawCall;
将UI控件分组,将一段时间内会发生变化的控件——比如怪物头顶的血条和伤害跳字放在同一个Panel上,并且这个Panel上只有这些控件,其余基本不变化的控件就放在别的Panel上。
》NGUI的DrawCall优化

1.少用Panel;

2.少用Atlas;

3.尽量避免夹层(即不同材质的UISprite相互间层级夹杂,如L2,L4使用mat1,L1,L3使用mat2,这样就形成夹层现象);


具体分层实现思路如下:

1.背景、按钮等置于底层,因为彼此间可能有层级关系,因此分配了1-4这么几个层级来放置底层UISprite;

2.文字展现基本置于顶层,因此把所有UILabel的层次提高,如第5层这样的;

3.同一个UIPanel下的texture和font尽量放在同一个atlas下。也表达了另外一个意思,使用同一个atlas的元素尽量放在同一个UIPanel下面。

4.如果一个UIPanel下面使用了多个atlas,那么尽量让使用相同atlas的元素连续,尽量避免atlas交叉。


》优化锚点内部逻辑,使其只在必要时更新;
即使是在控件静止不动的情况下,控件的锚点也会每帧更新(见UIWidget.OnUpdate函数),而且它的更新是递归式的,使CPU占用率更高。因此我们修改了NGUI的内部代码,使锚点只在必要时更新。一般只在控件初始化和屏幕大小发生变化时更新即可。




猜你喜欢

转载自blog.csdn.net/chenxuezhi123/article/details/45330609