Unity学习笔记03:Unity事件函数(生命周期函数)
官方手册说明
首先是官方手册中经典的生命周期函数执行顺序流程图。
官方手册链接
笔记总结
一个很容易误解的点
官方的流程图是单个MonoBehaviour脚本事件函数的生命周期(原话:how Unity orders and repeats event functions over a script’s lifetime),对于不同MonoBehaviour间的事件函数,其生命周期有另外的规则。
例如:Unity保证同一MonoBehaviour内Awake永远比OnEnable先执行,但在整个场景范围内,Unity的执行顺序则是先执行完同一MonoBehaviour内的Awake和OnEnable,再执行下一个MonoBehaviour的Awake和OnEnable。假设初始场景中有A、B、C三个组件,此时若直接点击播放,事件执行顺序为:A.Awake()->A.OnEnable()->B.Awake()->B.OnEnable()->C.Awake()->C->OnEnable()。以上粒子ABC三者的顺序默认由加入场景的顺序决定,也可以进行如下图的项目设置来自定义顺序:
OnEnable、OnDisable的调用时机
物体A上的组件A的OnEnable的调用时机是三个要求的并集:组件A为enabled,物体A的activeself为true,物体A的所有父物体(如果存在的化)也都为active。
反过来物体A上的组件A的OnDisable的调用时机则为这三个要求的交集:组件A为disabled,物体A的activeself为false,物体A的所有父物体(如果存在的化)中存在inactive。
Tips:传说之前的Unity版本中,对本身就是active的物体执行SetActive(true)同样会触发OnEnable,目前用的2021版本实测没有这个问题。
Update和FixedUpdate
一次循环中FixedUpdate在Update之前可能会调用多次,取决于项目设置中物理帧率的值。
协程相关
- 一次循环中协程会在所有Update事件函数和输入事件都完成后再调用,但在LateUpdate之前调用,但yield WaitForEndOfFrame是个例外。
- inactive对象上的所有协程都会被停止,但将某个MonoBehaviour脚本enabled设为false则不会停止协程。
Destroy操作的延迟生效
Destroy操作立即改变了对象内置的flag,立即触发所有组件的OnDisable,立即停止所有协程,但真正的销毁和OnDestroy的触发会在下一帧(实际上是当前帧的最后)才真正执行,虽然有DestroyImmediate方法,但Unity极不推荐,推测有性能问题。
Awake、Start函数可以设置为迭代器返回类型,OnEnable函数不可以
虽然编译器不会报错。