优化,老生常谈。游戏的优化和网站、软件优化没有任何不同,除了编码质量和使用技巧以外,都是那些空间<>时间、效果<>性能的老套路。
带*号的,都是极其重要的优化手段,就算没用上你也必须要懂。
Statistics
Profile
GC有两种触发方式,1内存不足自动触发,2手动触发。
首先内存不足时自动GC,经反复测试,并不是很好的办法。因为当内存不足时cpu压力也比较大,在GC之前就已经会发生卡顿现象,GC时还会发生更严重的卡顿。最好的办法还是手动GC。但一定要设计好触发条件。因为过于频繁的GC也很影响性能。
foreach会涉及到迭代器的使用,而据传每次循环所产生的迭代器会带来24 Bytes的垃圾。
比如if (object.tag == “target”)最好换成if (object.CompareTag (“target”))。因为访问物体的tag属性会在堆上额外的分配空间。
将场景中的对象放在池中调用,节省反复实例化的开销
脚本中三种调用Transform组件的方式,其响应时间有着巨大的不同,按时间的相应毫秒数大小排列的话是这个样子:GetComponen > transform= 60ms >myTransformCache
所以应该建立组件的引用留作复用,而不是每次都使用GetComponent。
使用void OnBecameVisible()和void OnBecameVisible()减少摄像机事业外脚本运行的开销。这两个函数分别是 当前物体在摄像机范围内或离开摄像机范围触发。
使用数组内建值,比如Vector3.zero而不是new Vector(0, 0, 0)。
设置位置旋转和缩放的时,不要使用高精度的变换。否则会产生模型抖动的问题。
类似前端的雪碧图。用一张包含了很多子贴图的大贴图,来代替一系列单独的小贴图。可以提高加载效率,并且更易于批量处理。
需要使用Renderer.sharedMaterial 代替Renderer.material
由于透明没有开启深度写入所以会造成overdraw。
共享材质可以减少材质数量,便于批量处理。
需要使用Renderer.sharedMaterial 代替Renderer.material
unity统合了纹理压缩的方法。只需按质量等级选择好即可。不过越高的压缩质量,画质越不好。GUI最好不要压缩,质量影响很明显。
【用法&步骤】
点击贴图文件 -> Inspector -> Default -> Compression 选择压缩质量
类似模型LOD技术,逐级生成多个低精度贴图,在适当的情况使用适当的贴图。缺点是会增加内存占用,典型的空间换时间优化。
【操作步骤】
点击贴图文件 -> Generate Mip Map -> Apply。
这时点击Sprite Editor打开窗口,拖拽右上角的拉杆就能看到结果了。
如果物体使用了多个Pass 的Shader,使用实时光照很有可能会造成性能下降。这是因为实时光照会产生更多的计算量,而且还无法使用动态批处理和静态批处理。
1 使用光照纹理烘焙技术(GI、bake),把光照提前烘焙到一张光照纹理(lightmap ),运行时映射相应的纹理实现光照效果 。这样不仅性能更好而且效果也更好。但缺点是物体必须设置为静态。对于需要移动的物体来说就不太合适。
2 这个时候使用灯光探针(Light Probe Group)是比较好的办法
3如果一定要使用更多的实时光,也可以选择用逐顶点光照来代替。
使用烘焙把静态物体的阴影信息存储到光照纹理中,只对动态物体使用适当的实时阴影。
这会减少顶点和三角面的处理。比如我们的相机在阳台,附近高楼林立。那么实际上只有前面几个楼需要前、左、右的面。远处的楼是不需要左或、右的面。因为看不到。
网格合并,材质合并,优化批处理
建模时应尽量减少模型的顶点。根据动态、静态批处理的触发相关规则,简单着色器模型顶点数必须小于900。如果着色器同时使用顶点位置、法线、UV值三种属性则模型顶点数必须小于300。如果着色器同时使用顶点位置、法线、UV0、UV1、切向量五种属性则模型顶点数必须小于180。
模型缩放会导致创建新的Batch。不利于动态、静态批处理
尽量使用cube collider 等内置colliser。性能会提高很多
使用模型的多级细节技术,在不同的距离使用不同精度的模型、材质。提升cpu、gpu型能,加重内存负担。典型的空间换时间优化技术。
【使用条件&步骤】
【使用条件&步骤】
点击目标物体,在Inspector窗口勾选Static。
要注意静态批处理不允许改变位置
相比较其他内置shader,mobile性能更好
优化对象数量 > 顶点运算 > 像素运算。
尽量不要把运算拖在片源元色器中计算。
1 float 计算速度最慢,适合存储顶点坐标,在顶点着色器中使用。
2 half 计算速度快些,适用纹理坐标等变量。
3 fixed 计算速度最快,适用于颜色变量和归一化后的方向矢量,适合在片元着色器中使用。
与模型的 LOD 技术类似, Shader的LOD技术可以根据条件启用shader片段,当Shader 的 LOD 值满足条件设才会渲染。
根据不同的硬件性能,选择性的启用特效。
由于被遮挡的物体无法通过深度测试,就不会再进行后面的渲染处理。
从前往后绘制,比从后往前绘制性能好的多。这是因为深度测试的存在减少了被遮挡部分的绘制。
【从前往后绘制的队列 - 不透明物体(Opaque)】
Shader中渲染队列值小于2500的对象都被认为是不透明(Opaque)的物体。如“Background"、“Geometry”、“Alpha Test”。
【从后往前绘制的队列 - 透明物体(Transparent)】
Shader中渲染队列值大于2500的对象都被认为是透明(Transparent)物体。如"Transparent"、"Overlay"等
尽可能地把物体的染队列值设置大于2500从而实现从前向后的渲染提升性能。
Build settings -> compression Method中设置压缩
剔除掉那些不在摄像机的视野范围内的对象,从而避免不必要的计算。
【用法&步骤】
点击摄像机 -> Inspector窗口 -> Camera组件 -> 勾选Occlusion Culling。
剔除掉那些被其他物体遮挡的看不到的物体,从而提升性能。
【用法&步骤】
unity工具栏 -> Windows -> Rending -> Occlusion culling -> Occlusion窗口 -> 作相关设置 -> Bake
指定特效作用范围,不要设置ervay thing。这是因为比如GUI之类的东西没有必要被计算。
GUI由于其特殊性大多需要设置成透明。如果GUI与场景物体一同西汉时,并且屏幕占比太多,就会造成很多不必要的overdraw。
可以用两个相机分别渲染ui和场景。
降低屏幕分辨率是 非常有效 的性能优化手段。尤其对于大屏幕低配置的设备。这时可以使用等比例缩小屏幕分辨率的方法来适当优化。用部分效果来换取性能山的提升
【用法&步骤】
///这里作等比例运算,适配过长或过宽的设备
{
//获取当前分辨率
int width = Screen.currentResolution.width;
int height = Screen.currentResolution.height;
}
///
//设置当前分辨率
Screen.SetResolution(640, 480,true);
对咯对咯忘记renderBuffer了
这个东东在渲染重复图形的时候会有高额的性能提升。基本原理就是将某一模型存入buffer,在目标位置重复调用渲染该buffer。比如地上的草。可以设置以人为中心,不断重复渲染预置范围内的草显示。 一个比较有名的例子就是和平精英手游。当你趴在草中的时候你会草遮挡,但远处的人看你的时候,你就是趴在光秃秃的地上。有人误认为是lod技术,那是不对的。这个就是renderbuffer的典型应用。
unity官方移动平台优化文档
unity性能优化