具体实现:
Profile的打开方式
上面的红框表示正在追踪哪个区,下面的框表示具体的细节,这里是追踪CPU Usage
这里是追踪Rendering
CPU Usage显示细节可以选择Timeline模式,Hierarchy模式和Raw Hierarchy模式,这里选择第二种
在显示细节选项卡里还可选择showcalls,查看调用的方法名
这里我们只追踪脚本的表现,除下面几个选项外,取消勾选其他选项。
点击Record,运行游戏,暂停。
可以看到,在消耗特别高的这一帧,Physics2D有50.4%,两个脚本的Log语句也占了很多资源。
Log语句在我们写脚本调试代码时非常有用,但它的消耗特别高,所以在不需要时,特别是正式版本,一定删去。
在我们这个项目里没有用到任何Physics,但我们追踪到Physics2d占了很多资源,是因为SceneContorller上挂了有Collider2D的prefab,即使这个Prefab没有在游戏里调用,它也会占资源。
因为这里我们不需要此collider,所以删掉。
这是修改Debug语句和删除Collider前的cpu使用和内存消耗情况
修改后的对比,cpu占用降低,内存特别是GC Allocated更加规律消耗小。
1.Update()每一帧都调用一次,即使你只写了一个空的Update也是,这造成了不必要的CPU占用。如果没有在Update里写东西,就把该Update()删掉
2.有一个脚本如下,作用是每秒换一次对象的颜色。注意在Update()里计数并隔多少秒我们就做什么,这种写法我一直用。但这是不必要的消耗CPU,只有每帧都需要调用的,比如移动等才应该放在里面。
在Profile的CPU Usage里表现
改成下面这种,这在该系列教程中,哥布林在地图的巡逻中使用过。在Start()里使用InvokeRepeating(方法名,第一次调用的时间点,之后每隔多久调用一次),就可以达到同样的效果,但是节省了性能。
再看改后的Profile,Invoke时依旧,但不调用时性能使用降低
要达到每隔一段时间做什么,还可以通过Coroutine实现
通过Coroutine实现从Profile里看在调用时比上面的InvokeRepeating耗能多些,但不调用时都不在这块儿耗能。
声明一个变量系统会分配缓存,来储存对值或对象的引用。一般不应该放在Update()里。
修改后可以看到内存占用变低
Vector2和Vector3是很昂贵的计算消耗。下面调用了两次Vector2.Distance
我们把它改一下
要查看某一块或某一句对性能的影响,我们可以使用如下语句,把想查看的部分放在中间。
我们可以看到此帧Update计算使用3.13ms中,这一句就占了2.08ms。
查看两者的计算速度对比,可以看到性能略有提升
下面的脚本一直调用Camera.main,我们来看效果
如果想要查看更具体的效果,点选Deep Profile,它会显示出更多调用细节。这对电脑性能消耗很高,所以尽量用在已经发现问题,但找不出原因时。
看到吗,Camera.main和Color.black不停在消耗,所以避免。像之前脚本里一样,在Start里把主相机存入变量
同样的transform.position,下面的除了get set 还要不停调用component tranform
这同样在Instantiate和Destory里,下面我们避免这种高昂消耗,学习对象池。
一个飞船不停发射子弹的项目,飞船每隔0.33生成子弹
子弹向上走,走到边缘销毁。注意子弹移动使用Coroutine而不是放在Update里。
现在我们给飞船写给对象池,注意里面补充池对象的语句
然后修改飞船控制脚本和子弹脚本,由instantiate,destory转换为setactive true or false
注意由子弹脚本的Start()改为OnEnable()
注意对象池只是避免了不停大量的Instantiate和Destory,如果只需要少量的生成销毁,则池是不划算的。
对象池一般用在子弹发射之类,战斗伤害跳字也可以使用。