本文共 1561 字,大约阅读时间需要 5 分钟。
在Unity中实现事件系统有两种方式:一种是使用C#内建的event关键字,另一种是UnityEvent类。有开发者对二者的性能分别进行了详细的分析,本文将为大家分享两种方式的对比及各自的适用场景。 首先要说明的是,
UnityEvent的初衷是方便开发者直接在检视面板中编辑事件及事件回调函数,简化开发流程。使用C#内置的event需要手动编写代码且无法直接编辑。建议开发者按照需求来选择合适的方式。 下面为大家介绍对比情况。
首先来看一下C#的event:
如此,我们就简单地实现了C#内建的事件系统。现在再来看看Unity中的UnityEvent类:
这里比较特别的是你需要让类拓展UnityEvent,或者如果不需要传参就跳过这一步。总之,你要为需要定义的事件创建新类并标记为[Serializable]。除此之外,它的使用方法和C#的event非常相似。
现在开始对比C# event和UnityEvent。首先看一下向它们添加监听函数的内存消耗状况,以下是一小段测试脚本:
接下来从Unity编辑器中打开Profiler面板,启用Deep Profile模式,然后运行程序,结果如下:
一开始C# event产生的内存垃圾比UnityEvent少,但是从添加第二个监听函数开始就比UnityEvent多了,随着监听函数的增多,二者之间的差距也越来越大。所以说如果你只注册不超过一个监听函数的话,可以使用C#的event。如果需要注册更多就可以使用UnityEvent(产生的内存垃圾较少)。
那么事件触发情况又将是怎样的?下面提供了一个测试程序,其中分别触发了带有两个监听器的不同事件系统:
同样,使用Unity编辑器中的Profiler面板查看结果:
触发事件时,C# event不会产生任何内存垃圾,但UnityEvent却产生了136个字节的垃圾,这一轮C# event完胜。
注意:UnityEvent只会在首次触发事件时产生垃圾,之后便不会再产生垃圾。
最后测试一下触发一组事件的性能情况。因为直接测试的结果数值很小不直观,所以接下来的测试会分别对带有0,1,2个参数的事件分别触发1000万次以做观测。
如果你想自己测试,只需新建Unity工程,在Assets目录中新建TestScript.cs脚本并复制粘贴以上代码,新建场景,将脚本附加到相机游戏对象上。然后以非开发模式64位进行编译,最后以640x480的窗口分辨率和最低画质运行,测试所用硬件环境及打包配置如下:
-
2.3 Ghz Intel Core i7-3615QM
-
Mac OS X 10.11.2
-
Apple SSD SM256E, HFS+ format
-
Unity 5.3.1f1, Mac OS X Standalone, x86_64, non-development
-
640×480, Fastest, Windowed
结果如下:
C#的event在所有的批量测试上都优于UnityEvent,而且触发事件越多,差距越大。最好情况下,UnityEvent花费的时间是C# event的2.25倍,但最坏情况则达到了40倍。
结论
如果不添加或只添加一个监听函数,UnityEvent产生的垃圾就比C# event少,反之则要多。 UnityEvent首次触发事件时会产生垃圾,而C# event不会产生任何垃圾,且前者的速度比后者慢两倍之多。
如果仅从性能角度出发,选择C#内置的event较为合适。但考虑到方便编辑简化流程且同时支持跨平台,则选用UnityEvent更恰当。 以上对比分析来源于:jacksondunstan.com
原作者:Jackson Dunstan