unity3d优化:不过早做优化,用户不容易察觉,消耗的时间是做出来的时间的几倍乃至几十倍也不一定出效果.
CPU优化
GPU优化
Memory优化
场景优化
移动平台(手机Android/iOS)优化
1:2D游戏 图片设置为Sprite(2D and UI)时 Generate Mip Maps 选项不选择(去掉勾选),Mit Maps多级纹理,是逐步缩小图像版本的一个列表,远离相机的物体使用较小的纹理版本,这个对于UGUI来说没什么用处,还会造成图片模糊和多使用33%以上的内存。Defult里面的Max Size不要超过2048,否则让美术重新切图.
2:碰撞盒将 Is Trigger 勾选上,CPU计算量减少.如果有空方法,尽量屏蔽之后再打包.update系列方法能少用,尽量少用.
3:GetComponent<>方法消耗CPU,尽量在脚本刚加载时缓存物体,不要在系统调用次数过多的方法中(例如update/fixedupdate/lateupdate等)调用此方法.GameObject go = null;go.transform 等价于 go.GetComponent(),所以再使用时,最好对这个transform 声明一个变量(一般这个地方是继承自一个基类,在基类里面进行声明);GameObject.FindWithTag("cube");//这一系列方法消耗比较小, //GameObject.Find("cube");//消耗比较大;
4:if小技巧,当在每单位时间内重复执行的函数中,写不要多次写if() if() if()需要改成if()else if()else if() 这样聚少成多,会节省CPU资源.
5:UGUI小技巧,Text不需要使用富文本的时候不要勾选RichText选项.删除空的Update方法。当通过Assets目录创建新的脚本时,脚本里会包括一个Update方法,当你不使用时删除它。调用大量的System.IO中的方法时,放在Coroutine(协程)中调用.
6:Draw call 就是SetPass calls,SetPass calls就是Draw call :
Draw call batching DC渲染顶点数据,unity3d采用2种情况解决,1:Dynamic batching,(动态批处理)对于比较小的网格顶点,将其相似的分成一组,进行一次性渲染,会耗费CPU资源,一次性可以处理少于包含900个顶点(vertex)的网格(Meshes ),系统自动做.2:Static batching (静态批处理):将静态(不移动)GameObject组合成大型Meshes,并以更快的方式渲染它们,需要手动选择处理.缺点是:动态批处理消耗CPU资源,静态批处理内存开销大.
Dynamic batching和 graphics jobs (see Player Settings),不兼容.条件:只有相同的Material 材质才可以批处理.例子:材质相同,纹理不同的2个物体,可以将纹理合并成为一个大纹理,这样可以进行批处理.使用Renderer.sharedMaterial 保持材质共享.例子:Material 材质不同,在渲染时Shadow 阴影可以一起批处理,与纹理不相关.
动态批处理:使用同一个材质,同一个shader,shader数值还要相同,所有统一缩放(scale)的物体但是尺度(x/y/z)不一样的不会进行批处理,反之则会.使用不同材质的实例化物体(instance)将会导致批处理失败。拥有lightmap的物体将不会进行批处理(当然,如果物体在环境中都相同,则会进行批处理),预设体的实例会自动地使用相同的网格模型和材质.
Static batching:当有相同的material材质,并且物体不移动/缩放/旋转等,可以使用静态批处理.不要讲树木标记为静态,会占用大量内存开销.以及在灯光效果比较强烈的情况下,不建议使用静态批处理,除非此物体不会受灯光影响.
使用Mesh Renderers,Trail Renderers,Line Renderers,Particle Systems,Sprite Renderers可以被批处理,skinned Meshes, Cloth, 其他类型的rendering不会被批处理.
7:使用层次而不是标签。我们可以轻松为对象分配层次和标签,并查询特定对象,但是涉及碰撞逻辑时,层次至少在运行表现上会更有明显优势。更快的物理计算和更少的无用分配内存是使用层次的基本原因。
8:将 Fixed Timestep (默认0.02,可以修改)设置一个比较适合的时间,fixedupdate方法刷新过快影响性能,刷新过慢用户体验不好.需要一个适度值.
9:减少角色控制器(Character Controller)移动命令的调用。移动角色控制器会同步发生,每次调用都会耗损极大的性能。我们的做法是缓存每帧的移动请求,并且仅运用一次。http://www.ceeger.com/Components/class-CharacterController.html 避免多次回调ControllerColliderHit函数.
10:面对性能更弱的设备,要用skinned mesh代替physics cloth。cloth参数在运行表现中发挥重要作用,如果你肯花些时间找到美学与运行表现之间的平衡点,就可以获得理想的结果。在物理模拟过程中不要使用Ragdolls,只有在必要时才让它生效尽量少使用Ragdolls(布娃娃系统),只有在必要时才让它生效。
11:对于性能较差的硬件,尽量避免使用碰撞器与物理效果,使用代码进行模拟.
12:尽量减少函数调用栈,能用自己写的一句话一个运算就能完成的,不要调用系统函数,不要使用SendMessage之类的方法,他比直接调用方法慢了100倍,你可以直接调用或通过C#的委托来实现。
13:优化数学运算,尽量避免使用float,而使用int,特别是在手机游戏中,尽量少用复杂的数学函数,比如sin,cos等函数。改除法/为乘法,例如:使用x*0.5f而不是 x/2.0f 。
14:压缩一切可以压缩的,如mesh texture material等
15:OnGUI方法少用,尽量不用,尽量避免数据拷贝.
16:尽量少使用粒子,看得过去即可.lightmap静态时,使用烘焙过后的静态图片进行替换,如果是动态烘焙,尽量减少烘焙的点.不要将一个场景做成一个完整的物体,要做成分块,为了优化效率.关闭阴影渲染,使用面片(图片),将物体贴上去.
18:使用图集,不使用很多图片,图集控制在1024x1024之下.对每一张图片进行压缩iOS使用PVRTC,Android使用ETC,让美术减少动画帧数,减少渲染顶点数.
19:性能优化:减小资源占用的内存,减少占用GPU的资源并保障游戏体验.优化的目标:游戏流畅的运行60帧/30帧/24帧,避免卡顿(图片解析,文件存储,大量敌人,网络连接等),30帧是手游端常用帧数.硬件兼容(CPU,GPU等),安装包减负. 常见的性能黑点指的是将正确的代码放在了错误的地方(系统也会产生性能黑点).
20:①安装包的优化;②资源包的优化;③流程结构优化:即用户操作较少,达到较多的功能.
21:体验优化:对动画,画面协调度,FPS的优化等.
22:评估性能工具unity3d Profiler :需要知道以下知识,1000毫秒=1秒 ; F P S 是 侦/秒 30FPS= 30/(1000ms),如果是每帧多少时间:1000/30=33.33ms 就是每帧33.33ms这是手游开发的正常频率 即在Profiler中看到毫秒数越小,后面帧率越大,则性能越好.在同一个方法中:total数值和self数值相对,total表示这个方法总共占用了多少资源(百分比形式),self表示这个方法自己占用了多少资源(百分比形式),其他资源占用是由此方法中的其他代码所占用表示为total-self.然后在看这个方法所占用的Time ms数,在手游里面如果超过了33.33ms就表示需要进行优化.
23:数学计算优化:尽可能用简单的计算获取开发的效率,减小数学计算的精度.
①计算距离:Vector3.Magnitude 消耗大,多了一步开平方 以及 Vector3.SqrMagnitude 消耗小,没有开平方,比如:大量计算敌人距离主角的距离是否比其他物体距离主角较近,只需要使用 Vector3.SqrMagnitude 消耗小的函数即可实现.② 计算敌人和主角的方位:Vector3.Angle计算夹角 ,但这个函数使用了较多的数学运算,有时候我们就直接使用Vector3.Dot(dot当其值大于0表示两个向量同向,当其值等于0表示2个向量互相垂直,当其小于0表示2个值相反,同向为1,反向为-1)点积这个函数即可;③Vector3.Cross(叉积(向量,其值又可以称之为垂直于2条向量的法线));
24:对象池:使用对象池管理子弹/炮弹,音频,敌人等大量重复使用的对象.1:首先生成一定数量的对象,使其处于懒惰状态; 2:使用对象时,先找到懒惰的对象,激活,变成活跃对象,如果数量不够,就需要重新创建对象; 3:销毁对象,意思是将活跃对象变成懒惰对象,并不是真正的销毁; 4:优化pool,加入时间概念,间隔一段时间,将对象设置成为懒惰状态; 5:使用第三方插件;
25:Mesh(网格):在Game视窗中点击Stats按钮检测Tris(三角形)手游端不要超过60K或者80K,PC端是200K/300K ,具体数值需要查看官网文档;可能模型本身并没有那么高的Tris和Verts(顶点),但是经过光照,产生的阴影,就会产生很多Tris和Verts;在一个灯光组件上面选中ShadowType把选项选成No Shadows则会大量减少Tris和Verts;
如何减少Tris和Verts呢? 当摄像机拉远时,物体身上某些顶点和面是可以被忽略的,也就是人眼看不到特别精细的物件,就可以将其忽略,不让GPU进行渲染,一是需要美术将其模糊化之后的模型新建一个出来,逐级递减Tris和Verts(美术会觉得累,不想做),二是游戏开发人员做优化,利用插件(不太精细,出现各种问题等),比如Simple LOD插件,https://blog.csdn.net/csdn_cjt/article/details/51498059 插件生成了3个Mesh,配上最原始的Mesh之后需要我们如何去写脚本呢?(可以同屏更多的敌人),例子是非常简单的原理,具体的插件里面自带脚本即可实现
26 material(材质):SetPass calls 当手游端这个超过60/80 ,PC端超过300 一般需要进行优化.模型和光照,阴影,2d图片等都会产生SetPass calls;
2d图片在场景里面使用的一个material就是一个SetPass calls,系统会对图片进行打包成图集,在设置图片的时候Max Size最大不要超过2048,但是一个需要展示特别精细的图最好不要打进图集,如何进行打包呢?将图片设置成为Sprite(2D and UI) 在下面的Packing Tag 填入数值,之后在Edit->Project Settings->Editor里面 将Sprite Packer中的mode 选成 Always Enabled(legacy Sprite Packer),然后在选择window->Sprite Packer
当我们在这个地方打进去多张图时,再次使用这张图集里面的2d图片的时候,这张图片里面的各种图组合在一起只会出现一次SetPass calls.
3D 物体在使用同一个材质的时候多次复制此物体SetPass calls不会增加,增加的是Batches ,使用不同的材质会增加一次SetPass calls;这就需要合并材质如:https://blog.csdn.net/dardgen2015/article/details/51517860
27 剔除 Camera设置Occlusion Culling为true表示支持遮挡剔除,此时没有效果,需要先打开window->Occlusion Culling 然后进行选择bake才有效果,首先需要这个物体设置成为Occluder static ,设置这个物体时,会读条,此时再计算光照和阴影.在Occlusion面板中,Smallest Occluder属性表示任何长和宽大于此值才会挡住后面的物体.bake之后随着镜头的移动,物体如果不在摄像机照射范围之内,则会被剔除;系统的这个剔除会产生某些不完美,当用户不察觉时,不必在意;
28 光照 在游戏场景中,当物体叫多时,是亟待并且急需优化的,是最重要的.Light组件里面有一个mode选项,将其选成baked选择.移动端现在不能支持Linear Space 但是支持Gamma Space;原理是将实时的场景bake成为几张图片,然后将图贴在场景中,极大的降低了SetPass calls ;此时再将一个物体放置进场景中,将不会产生光照和阴影效果,我们需要另一个东西Light Probe Group 光照探针,作用是让动态的物体可以受到静态光源的效果;
29 碰撞 Collider尽可能简单,即尽可能少使用Mesh Collider,尽可能组合使用简单的Collider; rigidbody在被激活情况下,尽可能少用,碰撞体的检测方式Collision Detection 是否持续/动态检测等方式,先选择消耗最小的,如果不能满足条件,则选择消耗较大的.
30 打包优化:在File->Build Settings -> Switch Platform /Player Settings->other Settings->Configuration下面有个Api Compatibility Level 有2个选项,一个是完整的.net 2.0版本,一个是.net 2.0 subset 子集(简化版,这个选项可以节省打包的资源);下面有一个Stripping Level,后面的选项是逐级递减资源,也就是当你选择use micro mscorlib 表示在发布的时候使用最小的代码量,大约会有几M的差别;图片psd/png/jpg ,最好使用psd导入unity3d里面,在里面做优化,在这张图片的inspector里面的Max Size参数选择较小的size,将其透明通道关闭(如果有属性alpha source 选择none,减少图片的大小),音频文件opus(未来主流)/ogg/mp3/wav,逐级质量变大.模型文件共用AnimationClip;在控制台右上角有个open editor log 打开文本文件,查找问题;
31:插件介绍:utomate 节点编程,针对iOS和安卓打包,当你设置成功之后,自动打包,你可以去做其他事情,不必紧盯屏幕.debug 插件 SRDebugger,在真机上面右上角连点3次,就会出现一些系统记录的debug.log信息.
32:http://forum.china.unity3d.com/thread-32492-1-1.html