Unity性能优化
Profiler
Profiler是unity官方提供的检测运行效率的工具,在Unity面板中按Ctrl+7即可调出工具面板。
Unity提供很多种,但是我们常用的只有三种,CPU,Rendering(渲染),和Memory(内存)。
使用步骤
点击CPU模块,然后将面板属性改为Hierarchy,然后我们写上一个简单的脚本,运行测试一下。
public class ProfilerTest : MonoBehaviour
{
void Update()
{
Test();
}
void Test()
{
Debug.Log("AAA");
}
}
在程序运行的时候,在Cpu面板中随便点击一个地方,我们发现下面的属性面板已经显示了我们脚本的性能消耗,但是并没有显示出具体的Test方法,此时我们需要勾选上Profiler面板中的Deep Profile(可以理解为深度检测),然后Reload。
然后我们重新运行一下。
接下来我们就发现显示了具体的Test方法,然后是Test里的Debug.log。
Deep Profile使用注意点
使用DeepProfile的时候会产生性能消耗,如果是本来就在战斗情况下,或者消耗比较大的情况,使用Deep Profile反而会起到反效果,因此我们有俩种情况去避免。
1:将想检测的功能模块单独的提取出来单独测试。
2:如果功能模块耦合比较严重,不好单独提取,我们可以使用Profiler类中提供的方法。
public class ProfilerTest : MonoBehaviour
{
void Update()
{
Profiler.BeginSample("Current Profiler");
Test();
Profiler.EndSample();
}
void Test()
{
Debug.Log("AAA");
}
}
可以看到,Profiler检测到了固定的方法性能消耗,与上面的一样开销。
工作吐槽
上家工作的时候,项目组是新开的,主程是一个工作不到两年经验的新人,还是从培训班出来的,真的是吐了,要发布版本的时候发现性能开销比较大,然后他又不会详细的去测,就只是简单的测了一下,发现是我写的脚本开销比较大,然后就让我改,然后我就用Deep Profile测出来是我调用他提供的数据保存方法造成了3MB的开销,然后我让他自己改回去。遇到这种同事时真的挺心累的,什么工作都是踢皮球,每次都要我将数据实时甩到他脸上他才愿意去做。然后!我就离职了。
v0.2版本,新增Profiler介绍
优化分为两大类:
渲染优化(GPU):
GPU优化主要是针对DrawCall这个参数,这个参数具体是什么可以自行百度,这里不做过多解释。
举个最简单的例子,复制一个1G的文件到另一个位置,与复制1024个1M的文件到另一个位置,肯定是复制1G的快。
所以DrawCall也是一样,每次调用DrawCall都可以理解为有准备工作与善后工作,我们需要做的就是讲能合并的DrawCall合并,减少准备工作与善后工作的次数。
1:层级细节LOD技术
即不同距离下渲染的物体不一样,例如近距离就渲染高精度的模型,距离远了之后渲染低精度的模型。
主要用到的组件是LOD Group。
三个层级分别添加不同的模型。
2:遮挡剔除
将需要渲染的游戏物体改为
在window=》Occlusion中将参数设置如下
Bake之后选中camera,即可实现优化,即只渲染在目标视野中的物体。
3:光照贴图合并
具体可以参考我的这一篇文章。
灯光与渲染
4:Mesh合并
所有物体都是三点一个片面搭建出来的,最终会由MeshRender绘制出来,但是数量过多会增多DrawCall的数量,所以我们可以对Mesh进行合并,然后统一交给Mesh去渲染。
void MeshCombine()
{
MeshFilter[] filters = GetComponentsInChildren<MeshFilter>();
CombineInstance[] combiners = new CombineInstance[filters.Length];
for(int i = 0; i < filters.Length; i++)
{
combiners[i].mesh = filters[i].sharedMesh;
combiners[i].transform = filters[i].transform.localToWorldMatrix;
}
Mesh finalMesh = new Mesh();
finalMesh.CombineMeshes(combiners);
GetComponent<MeshFilter>().sharedMesh = finalMesh;
}
CPU优化:
对象池的应用等