做优化首先先要会看Game视图的Status参数
1、FPS
fps其实就是 frames per second,也就是每一秒游戏执行的帧数,这个数值越小,说明游戏越卡。
2、Draw calls
batching之后渲染mesh的数量,和当前渲染到的网格的材质球数量有关。
3、Saved by batching
渲染的批处理数量,这是引擎将多个对象的绘制进行合并从而减少CPU的开销;
很多GUI插件的一个好处就是合并多个对象的渲染,从而降低DrawCalls ,保证游戏帧数。
4、Tris 当前绘制的三角面数
5、Verts 当前绘制的顶点数
6、Used Textures 当前帧用于渲染的图片占用内存大小
7、Render Textures 渲染的图片占用内存大小,也就是当然渲染的物体的材质上的纹理总内存占用
8、VRAM usage 显存的使用情况,VRAM总大小取决于你的显卡的显存
9、VBO Total 渲染过程中上载到图形卡的网格的数量,这里注意一点就是缩放的物体可能需要额外的开销。
10、Visible Skinned Meshes 蒙皮网格的渲染数量
11、Animations 播放动画的数量
手机优化简单说一下,主要三个方面一个资源方面、引擎方面优化、代码方面优化。
美术资源包括:动态物体、静态物体、纹理数据、音频数据。
动态物体:游戏主角、怪物、NPC等
控制面片数量:300-2000面片。
控制Skinned Mesh Render 为1个。
控制材质数量:1-3个(有多少个材质就会渲染几次,最好渲染一次,除非你有部分换装需求)
控制骨骼数量:小于30根。
静态物体:场景
控制网格顶点数量:小于500个
标记为Static。
Animation组件:没有用就删掉。
自带地形:控制地形的分辨率高度尺寸小于257,纹理最好不要超过4个。
纹理数据:纹理格式尽量压缩,纹理尺寸长宽小于1024。
建议使用Mipmap。
音频数据:
播放时间长的音乐(背景音乐)可以使用OGG或MP3
播放短时间音乐可以使用.wav和.aif这样未压缩格式
引擎优化
光源设置:
1.控制场景中尽量不要有冗余的灯光,因为每多一个灯光就意味着渲染时产生一个pass,这样drawcall就会越多,从而增加负担。
那么我们也可以设置Pixel Light Count属性控制一个物体在同一时刻能被几个Light渲染。(Edit-》Project Setting-》Pixel Light Count 如下图)。但是这个 参数无法影响important光源。
2.Light组件有一个属性Render Mode 有三个值(Auto、important、No Important),No important指的是灯光进行顶点渲染,这种渲染比较粗糙无法实现阴影等功能,important指的是灯光采用像素渲染,看起来效果更好,反之消耗资源。最好场景中只有一个Important光源。
相机设置
咱们不要渲染远距离看不到的东西了。
粒子特效
建议小于200个粒子,每个粒子发射器粒子总数建议不超过过50个。
物理引擎
碰撞体控制没有非常精确要求的情况下最好使用Box Collider和Sphere Collider,尽量不要用Mesh Collider。
渲染优化
尽可能不要使用Alpha Test和Alpha Blend。
DrawCall Batching。最好使用相同的材质,这样DrawCall就只会渲染一次。(这个是优化的主要途径)。无论是动态物体还是静态物体都适用。注意动态物体小于900个顶点的会动态Batch,并且和使用的Shade属性有关,适用Position、UV等属性越多,能自动Batch的顶点就越小。
纹理合并:当两个物体的适用的Shade一样但是纹理不一样时,我们可以使用纹理合并,让Unity认为这是一个个材质,从而降低DrawCall的值。
遮挡剔除(Occlusion Culling):剔除摄像机拍摄不到的物体。
代码优化
1.对于有的函数,可以每隔几帧执行的
void Update(){
if(Time.framCount%6==0){DoSomething();}
}
2.定时重复调用可以使用InvokeRepeating函数实现,比如,启动0.5秒后每隔1秒执行一次 DoSomeThing 函数
void Start()
{
InvokeRepeating("DoSomeThing", 0.5f, 1.0f);
}
3.
少使用临时变量,特别是在Update OnGUI等实时调用的函数中。
void Update()
{
Vector3 pos;
pos=transform.position;
}
这样写
private Vector3 pos;
void Update()
{
pos=transform.position;
}
5. 主动进行垃圾回收
void Update()
{
if(Time.frameCount%50==0)
{
System.GC.Collection();
}
}
6.
优化数学运算,尽量避免使用float,而使用int,特别是在手机游戏中,尽量少用复杂的数学函数,比如sin,cos等函数。改除法/为乘法,例如:使用x*0.5f而不是 x/2.0f 。
7.引用一个游戏对象的最合乎逻辑的组件。有人可能会这样写someGameObject.transform,gameObject.rigidbody.transform.gameObject.rigidbody.transform,但是这样做了一些不必要的工作,你可以在最开始的地方引用它,像这样:
privateTransform myTrans;
void Awake()
{
myTrans=transform;
}
8.
协同是一个好方法。可以使用协同程序来代替不必每帧都执行的方法。(还有InvokeRepeating方法也是一个好的取代Update的方法)。
9.尽可能不要再Update或FixedUpdate中使用搜索方法(例如GameObject.Find()),你可以像前面那样在Start方法里获得它。
10.不要使用SendMessage之类的方法,他比直接调用方法慢了100倍,你可以直接调用或通过C#的委托来实现。
11.使用javascript或Boo语言时,你最好确定变量的类型,不要使用动态类型,这样会降低效率,你可以在脚本开头使用#pragmastrict 来检查,这样当你编译你的游戏时就不会出现莫名其妙的错误了。