包含此页的版本:
不含此页的版本:
在内部,Unity 会跟踪对其回调感兴趣的对象列表,例如Update,FixedUpdate和LateUpdate. Unity 将这些列表作为侵入式链表进行维护,以确保列表更新在恒定的时间内发生。MonoBehaviour 实例在启用或禁用时分别添加到这些列表中或从中删除它们。
虽然将适当的回调添加到需要它们的 MonoBehaviour 实例很方便,但随着回调数量的增加,这会变得更加低效。从本机代码调用托管代码回调有一个小而大的开销。这会导致在调用大量每帧方法时帧时间下降,在实例化包含大量 MonoBehaviour 的预制件时导致实例化时间下降。实例化开销是由于调用的性能开销造成的Awake和OnEnable每个组件的回调预制件一种资产类型,允许您存储包含组件和属性的游戏对象。预制件充当模板,您可以从中在场景中创建新的对象实例。更多信息
请参阅术语表.
当具有每帧回调的 MonoBehaviour 实例数量增长到数百或数千个时,删除这些回调并让 MonoBehaviour(甚至标准 C# 对象)附加到全局更新管理器单例是有利的。然后,此更新管理器单例可以分发Update,LateUpdate,以及对感兴趣对象的其他回调。这还有一个额外的好处,即允许代码在回调无作时取消订阅回调,从而减少每帧必须调用的函数数量。
最大的节省通常是通过消除很少执行的回调来实现的。考虑以下伪代码:
void Update() {
if(!someVeryRareCondition) { return; }
// … some operation …
}
如果有大量 MonoBehavioursUpdate与上一个类似的回调,然后运行所消耗的大量时间Update回调用于在本机代码域和托管代码域之间切换以执行 MonoBehaviour,然后立即退出。如果这些类仅订阅全局更新管理器,则someVeryRareCondition为 true,然后取消订阅,则在切换代码域和评估罕见条件上花费的时间更少。