1、光照烘焙(Baked Lighting)
关闭实时阴影,得到实时阴影的物体将无法被批处理,导致大量的额外绘制调用的开销。在PC上,你仅能通过单一的即时方向光来得到不错的动态阴影,但在移动端请用烘焙好的光照,不要用实时阴影。
2、纹理集合(Texture Atlasing)
每个不同材质都会至少导致一个新的绘制调用,你可能会以为一个木头门和铁椅子必须使用不同的材质,毕竟它们使用了不同的纹理。但是如果它们能使用同样的着色器,你可以使用纹理集合来创建一个材质,同时兼容这两个物体。
一个纹理集合其实就是一个大纹理贴图,里面包含了各种各样的小纹理。你可以让某个材质加载几个纹理而非让一堆材质加载一堆纹理,每个物体都能通过不同的纹理映射来加载这个纹理集合上的不同坐标位置的一小片纹理。你也可以在绘制管线中手动生成纹理集,Juan Sebastian的Pro Draw Call Optimizer工具非常有用,它可以生成纹理集,并且在替换新对象时不会搞混资源。
3、动态批处理(Dynamic Batching)
移动非静态物品也能被动态批处理为单一绘制调用,这对于CPU来说开销较大,每帧都经过计算,但就优化最终结果来说还是不错的。不过要注意的是这只对低于900个顶点并有着同样材质的物体才有用,使用纹理集合来为你的动态物体创建一个单一材质,然后你就能得到简单的动态批处理了。
4、多细节层次(Level Of Details)
多细节层次组也是一个提升表现的简单方式。使用多个细节层次的Assets并让离镜头远的物体采取低细节的几何图形进行渲染,Unity能自动在摄像头和物体之间的距离发生改变时过渡到不同的细节层次。
5、关卡设计(Level Design)
如果你的游戏是让玩家从一个房间(地区)到另一个房间(地区),那基本的方式就是让整个游戏只在一个关卡中,但这样会导致过高的内存开销,每一个房间内的物体和材质都会被加载到内存里,即便在当前场景中是不可见的。所以,要将房间放到不同的关卡里,通过代码设计来分开加载。
6、异步加载(Asynchronous Loading)
当玩家快要接近到加载下一关的关门时,不要同时使用Application.LoadLevel()/现在的版本是SceneManager.LoadScene(),,,这会导致游戏暂停卡顿,即便头部跟踪只停了一小会儿,也会让玩家非常的不适。因此,要采取Application.LoadLevelAsync(),,,
7、静态批处理(Static Batching)
在一个场景里,可能有一堆静态几何图形,比如墙、椅子、灯光和各种静止网格(Mesh),你可以在编辑器里把它们标成静态,确保将他们标记成静态光源映射来得到烘焙好的光照贴图纹理。被标记成静态的物品会被组成一个网格,而非每绘制一次物品就产生调用。
但静态批处理有一个关键的要求:所有物品必须都有同样的材质。如果你有木头材质的静态墙壁和一个钢铁材质的静态椅子,所有墙壁会被组合成一个网格,消耗一个绘制调用,而椅子则也会有一个网格,占用另一个绘制调用。
8,更新不透明贴图的压缩格式为ETC 4bit,因为android市场的手机中的GPU有多种,
每家的GPU支持不同的压缩格式,但他们都兼容ETC格式,
对于透明贴图,我们只能选择RGBA 16bit 或者RGBA 32bit。
9,减少FPS,在ProjectSetting-> Quality中的
VSync Count 参数会影响你的FPS,EveryVBlank相当于FPS=60,EverySecondVBlank = 30;
这两种情况都不符合游戏的FPS的话,我们需要手动调整FPS,首先关闭垂直同步这个功能,然后在代码的Awake方法里手动设置FPS(Application.targetFrameRate = 45;)
降低FPS的好处:
1)省电,减少手机发热的情况;
2)能都稳定游戏FPS,减少出现卡顿的情况。
10,当我们设置了FPS后,再调整下Fixed timestep这个参数,
这个参数在ProjectSetting->Time中,目的是减少物理计算的次数,来提高游戏性能。
11, 尽量少使用Update LateUpdate FixedUpdate,这样也可以提升性能和节省电量。
多使用事件(不用SendMessage,使用自己写的,或者C#中的事件委托)。
12, 待机时,调整游戏的FPS为1,节省电量。
13,Instantiate实例化操作
一般情况下,我们不建议项目在运行过程中频繁地调用 Instantiate 和 Destroy 来创建和销毁一个GameObject。这种做法不仅可能会造成频繁且较高的CPU占用,更重要的是,它将造成大量的内存碎片,从而造成越来越多的堆内存分配,进而加速系统垃圾回收操作(Garbage Collection)的到来
14,Draw Call数量、Triangle数量 和 可见蒙皮网格数量
一般来说,Draw Call 数量、Triangle 数量 和 可见蒙皮网格数量 的推荐值需根据平台的不同而不同。对于 Mobile 低端移动设备来说,建议 Draw Call 数量的主要范围在 [0,200] 区间内,Triangle 数量保持在 10万 以下,可见蒙皮网格数量保持在 50 以下。
15,Contacts 数量、Rigidbody 数量 和 碰撞体数量
Contacts 数量为碰撞对(Contact Pair)数量。所谓“碰撞对”,是指当前空间中发生碰撞的物体之间的接触点,每个 “碰撞对” 均连接两个相互产生碰撞的物体。一般来说,Contacts 数量越大,则表明碰撞物体的数量越多,即物理系统的CPU开销越大。
Rigidibody数量 和 碰撞体数量, 其标准值需因运行平台的不同而不同。对于Mobile移动设备来说,建议 Rigidibody数量 控制在 50 以下,碰撞体数量(静态碰撞体和动态碰撞体) 控制在 100 以下。
UNITY3d在移动设备上的一些优化资源的方法
1.使用assetbundle,实现资源分离和共享,将内存控制到200m之内,同时也可以实现资源的在线更新
2.顶点数对渲染无论是cpu还是gpu都是压力最大的贡献者,降低顶点数到8万以下,fps稳定到了30帧左右
3.只使用一盏动态光,不是用阴影,不使用光照探头
粒子系统是cpu上的大头
4.剪裁粒子系统
5.合并同时出现的粒子系统
6.自己实现轻量级的粒子系统
animator也是一个效率奇差的地方
7.把不需要跟骨骼动画和动作过渡的地方全部使用animation,控制骨骼数量在30根以下
8.animator出视野不更新
9.删除无意义的animator
10.animator的初始化很耗时(粒子上能不能尽量不用animator)
11.除主角外都不要跟骨骼运动apply root motion
12.绝对禁止掉那些不带刚体带包围盒的物体(static collider )运动
NUGI的代码效率很差,基本上runtime的时候对cpu的贡献和render不相上下
13每帧递归的计算finalalpha改为只有初始化和变动时计算
14去掉法线计算
15不要每帧计算viewsize 和windowsize
16filldrawcall时构建顶点缓存使用array.copy
17.代码剪裁:使用strip level ,使用.net2.0 subset
18.尽量减少smooth group
19.给美术定一个严格的经过科学验证的美术标准,并在U3D里面配以相应的检查工具