前言:
最近项目一直在做优化,然后发现Unity的其中一个大坑,关于EventSystem的。当玩家在连续操作屏幕的时候,就会触发EventSystem.Update() -->....-->EventSystem.RaycastAll();这个RaycastAll非常耗时,每帧七八毫秒、时机毫秒的情况都有。
虽然是Unity 的底层,但是还是要想办法来优化一下。
正文:
1、现状分析:
由上图我们可以看到,耗时的大头分别是:
GraphicRaycaster.get_eventCamera(); --------1.84ms
Graphic.get_canvasRenderer(); --------1.14ms+1.17ms=2.31ms
其中Graphic.get_canvasRenderer()总计调用了2次。这两个方法总计造成耗时4.15ms,占总共8.32ms的49.88%。如果能解决这两个的耗时问题,就能将这个函数的耗时减少一半,还是非常可观的。
2、优化GraphicRaycaster.get_eventCamera()
这个函数使用来获取当前UI的摄像机的,但是实际上相机都是与各个Canvas绑定的,按理来说一旦初始化之后,只要游戏内没有更改过相机,那么就应该一直是原来的相机。其实他的动态获取在兼容性上会好些,但是在性能上面是没有必要的。
优化这一个需要重写GraphicRaycaster,一般这个类会挂载在Canvas上面:
public class YHGraphicRaycaster : GraphicRaycaster
{
public Camera TargetCamera;
public override Camera eventCamera
{
get
{
if (TargetCamera == null)
{
TargetCamera = base.eventCamera;
}
return TargetCamera;
}
}
}
代码其实非常简单,然后只需要将这个YHGraphicRaycaster 挂载在Canvas下面,替换掉原来的Canvas可以了。
经过这么一堆操作,目前性能状况如下:
优化之后(YHGraphicRaycaster.get_eventCamera())剩余0.16ms,基本减少了2ms。其实可以看到其实还是有调用GraphicRaycaster.get_eventCamera(),说明还有哪里的GraphicRaycaster没有替换干净,只有再去项目里找找看在哪里。不过比较而言,原来的方法10次调用0.2ms,新方法76次调用0.16ms,区别还是很大的。
经过优化之后点击事件没有任何问题,亲测无Bug。
3、 优化Graphic.get_canvasRenderer()
正在研究中……