前言
最近在学习性能优化的内容,想写博客总结一下,这是我第一次写,所以可能会比较粗糙,后面会随着学习的深入不断完善
一、性能优化概述
学习性能优化之前你需要先知道什么是渲染管线,以及3D模型的基本知识,本文不给出相关教学
性能优化的主要目的就是提高游戏帧数,而提高游戏帧数可以从优化代码,降低DrawCall等方面入手,在Game窗口点击Stats可以查看DrawCall、帧数、顶点数量、三角形数量、SetPass等信息,这些都是我们要重点关注的数据,Batches是DrawCall进行批处理以后的值,你可以理解为DrawCall
二、Profiler工具的使用
1、Profiler与FrameDebugger是什么
Profiler是Unity内置的一款分析性能的工具,比Stats能看到更多的信息
在Window/Analysis/Profiler中可以打开Profiler窗口
用鼠标在图表上拖动就可以看到具体每一帧的帧长,以及具体每个部件分配的时间,开启Deep Proflie能看到更详细的方法占用,建议开启(说明:假如你的目标帧数是60帧,那么帧长就等于1000ms/60=16.7ms,也就是说CPU和GPU要在16.7毫秒内处理完这一帧的内容,如果不能处理完,那么就表现为掉帧)
看到密密麻麻的数据不要慌,我们常用的窗口主要就两个,CPU Usage和Rendering,前者能够查看代码调用、物理引擎处理、垃圾回收、渲染管线等部件的占用,后者能查看更详细的渲染相关的数据
查看图表的时候我们主要关注峰值(也就是那些突然耸起的部分),意味着这些地方占用比较大,也是我们优化的对象。以下是某一帧的Rendering信息,注意图表里的Dynamic Batching、Static Batching、Instancing,这三项是批处理相关的信息,也是后面会讲到的性能优化的常用方法
具体的参数信息可以查阅用户手册: Unity用户手册
FrameDebugger是与Profiler配套的一个小工具,能够查看每一帧图像的渲染顺序
2、注意事项
由于场景上的相机,光照,天空盒,背景等也需要DrawCall,所以不存在0DrawCall的情况。由于编辑器本身也要占用一部分性能,所以在编辑器窗口看到的并不是游戏最终发布出去的效果,如果想要进行非编辑器模式的性能分析,可以在BuildSetting中勾选Development Build,AutoConnectProfiler,游戏Build以后,运行时就会自动连接Profiler
下图为默认场景下的各部分占用时长,可以看到EditorLoop(编辑器)占用了2.69毫秒
BuildSetting设置
三、示例代码
创建一个在按下按键时创建5000个球的脚本,挂载到场景任意物体上,打开Profiler的录制功能,点击运行
public class Test1 : MonoBehaviour
{
public GameObject obj;
public Vector3 pos;
public int num = 5000;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
for (int i = 0; i < num; i++)
{
pos = new Vector3(Random.Range(0, 11), Random.Range(0, 11), Random.Range(0, 11));
Instantiate(obj, pos, Quaternion.identity);
}
}
}
}
按下W键,可以看到CPU占用突然升高,同时场景上创建出了数个小球,鼠标点击峰值部分,点击Total降序排序
可以找到在Update中,Instantiate调用了5000次,便是此次影响性能的罪魁祸首