Unity性能优化

移动开发 waitig 454℃ 百度已收录 0评论

1.Texture的长宽的大小最好是2次冥,2、4、8、16、32、64、128、256、512、1024、2048,如果不是由2次冥组成的贴图,那么图形将会多占用一些显卡的内存,读取贴图时也会变慢。

2.MipMaps,使用MipMaps的贴图会多占用百分之33的内存,但是可以大幅度提升效能,在UI的贴图下不使用MipMap。
MipMap的缺点会占用额外的内存,因为mipmap会根据摄像机的远距渲染不同像素质量的8个贴图,质量是2的幂次缩减。
MipMap的优点优化显存带宽,用来减少渲染,因为距离摄像机越远,像素质量越低,反之,越近越高。
MipMap一般用于不需要看清楚远处的地方,可以勾选MipMap

3.使用LOD Group组件,根据距离选择不同的模型,有效的优化了顶点和面片,但会占用更大的内存空间。

4.减少drallcall
(1) 使用批处理Batching 合并,动态批处理的条件是 合并的对象都用同一个材质球。
批处理分为 动态批处理和静态批处理。
动态批处理的好处都是自动进行的,物体能进行移动,而坏处是根据Unity一定的规则来进行运作,主要规则为 单模型总顶点数不大于900,scale缩放要保持一致,没使用lightmap的对象。
静态批处理的好处的自由度很高、限制少,但坏处是 会占用更多的内存、物体静态批处理后不能进行移动。

5.Texture 在Android下通常采用ETC4压缩格式

该面板是把该贴图强制转换成2次幂分辨率 ,取消GenerateMipMaps勾选,选用ET4压缩,一般适用于背景或者大图,如带Alpha的图需要使用Alpha分离Shader支持。
针对Sprite精灵只需要取消GenerateMipMaps 。

6.UITexture与Sprite的区别?
UITexture的功能在屏幕显示图片和Sprite类似,但它会消耗单独的DrawCall(性能开销) 去渲染,它是独立的存在,拥有自己独立的材质球和Shader。所以它会比Sprite占用更多的内存。
使用UITexture,遵循下面的规律:
1. 当图片过大,不适合图集时候,考虑使用UITexture, 并要尽量保证图片大小是2的N次方,这样在Unity中可以加快加载速度。
2. 当图片的使用频率不高,只在某些特殊场景下使用,可以考虑使用UITexture,比如游戏的结束和开始画面。
3. 当图片的修改更换特别麻烦时候,考虑使用UITexture。

7.打图集 减少dallcall 但会对应的增加内存消耗,中间取舍,平衡内存和dallcall消耗。

8.尽量不使用空的RawImage或者Image,因为它会占一个dallcall

9.优化GC

10.贴图UV滚动格式
若贴图不需要滚UV平铺的效果,则把贴图mode选择为clamp

若选择repeat,组有 UV动画,就是贴图UV 0-1的滚动。

11.对于android模式下 使用etc4压缩格式
在贴图不带有alpha通道的情况下 使用etc4压缩格式在android是较为合适的。

12.String 字符串
拼接字符串会产生GC,使用贴图Font每次赋值也会产生GC

13.场景卸载开销
(1)当加载新场景的时候,Unity会收集所有的非DontDestroyOnLoad的GameObject和Component,然后进行Destroy,同时OnDestroy的函数会被调用,这里的性能开销取决于OnDestory的回调函数中的代码逻辑
(2)在场景卸载的时候会调用Resouces.UnloadUnusedAssets函数,清空所有引用关系,该函数的耗时取决于Asset和Object的数量。

14.贴图纹理尺寸
一般来说,纹理尺寸越大,则占用内存越大,所以尽可能降低纹理尺寸,如果512×512的纹理对于效果已经够用,就没必要使用1024×1024 因为后者占用的内存是前者的四倍。

15.贴图纹理Read&Write读写权限
Unity中导入的每张贴图都有一个启用可读可写(Read/Write Enabled)的开关,对应的程序参数是TextureImporter.isReadable。选中贴图后可在Import
Setting选项卡中看到这个开关。只有打开这个开关,才可以对贴图使用Texture2D.GetPixel,读取或改写贴图资源的像素,但这就需要系统在内存里保留一份贴图的拷贝,以供CPU访问。

16.图集管理
一个界面尽量打成一个图集,且该界面的UI元素不要引用其他图集中的元素,这样会造成两份图集内存的占用。

17.降低贴图分辨率和屏幕分辨率
降低屏幕分辨率会使屏幕的像素点渲染数量减少,但是画质会对应下降,该方案针对手机端的很有用, 不到万不得已的时候,不用这招

18.避免频繁调SetActive
避免频繁调用GameObject.SetActive

19.减少Alpha贴图叠加次数,会导致GPU的高负荷渲染,具体可以使用overdraw工具查看叠加效果。

20.用什么工具都得有始有终,避免性能内存泄漏是关键。

21.Animator的使用,会造成大量的性能开销,所以在数量级别的动画,尽量用代码去实现,闲置的Animator也要enable去关闭掉,因为也会造成性能开销。

22.优化GC,尽量避免每帧都会产生GC 或者 突然造成大量GC的情况,GC的产生意味着mono垃圾的回收,每次回收都会造成突然卡顿。

23.Instantiate实例化对象要提前预加载对象,否则会造成明显的卡顿效果。

24.减少Camera的使用。

25.如若是3D大场景,可以适当的减少Camera的渲染距离,这样会把远处的物体的屏蔽掉,节约面数和定点数,减少渲染负荷。

26.Unity自带的物理引擎性能开销比较大,如只需要简单的判断是否碰撞到,用代码判断距离实现即可。

27.减少UI的刷新频率,可以间隔几帧去刷新,这样会减少UI的mesh合并次数。

28.贴图的异性向化处理,越大代表远处越清晰,不过越大造成的性能开销也会增多。

一。CPU优化
1.渲染模块 任何游戏中最为消耗CPU性能的引擎模块。
(1)。降低drawcall,drawcall越高,则渲染模块的CPU开销越大,降低drawcall的主要方法是减少渲染物体的材质种类,并通过drawcallBatching来减少数量
当我们使用Draw Call Batching将同种材质的网格模型拼合在一起时,可能会造成同一时间需要传输的数据(Texture、VB/IB等)大大增加,以至于造成带宽“堵塞”,在资源无法及时传输过去的情况下,GPU只能等待,从而反倒降低了游戏的运行帧率。
Draw Call和总线带宽是天平的两端,我们需要做的是尽可能维持天平的平衡,任何一边过高或过低,对性能来说都是无益的。

2.UI模块

  • 尽可能将动态UI元素和静态UI元素分离到不同的UIPanel/Canvas中(UI的重建以UIPanel(NGUI) / Canvas(UGUI)为单位),从而尽可能将因为变动的UI元素引起的重构控制在较小的范围内;
  • 尽可能让动态UI元素按照同步性进行划分,即运动频率不同的UI元素尽可能分离放在不同的UIPanel中;
  • 控制同一个UIPanel/Canvas中动态UI元素的数量,数量越多,所创建的Mesh越大,从而使得重构的开销显著增加。这种做法,其本质是从概率上尽可能降低单帧中UIPanel的重建开销。
  • Canvas越多,消耗的也越多,不能盲目的分离元素。



更多的优化技巧会随着工作的学习补充。


本文由【waitig】发表在等英博客
本文固定链接:Unity性能优化
欢迎关注本站官方公众号,每日都有干货分享!
等英博客官方公众号
点赞 (0)分享 (0)