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优化:
对象池的应用

猜你喜欢

转载自blog.csdn.net/qq_40629631/article/details/111911763