最近做项目,碰到当一个GameObject在脚本中enable或disable时,对这个GameObject的生命周期有点乱,特意重新去研究一下,整理一下,以免下次方便查看。
Unity完整的生命周期说明如下,这里没什么可说明的。关于Unity协程执行顺序为甚么这样可以参考我之前关于协程的一篇文章。这里协程的执行顺序也写得非常明白了。
这里OnApplicationPause事件执行的方式比较特殊,它一般在移动端或PC端从本身程序切换到外部或从外部切换回本身程序时执行。
参考:https://docs.unity3d.com/Manual/ExecutionOrder.html?_ga=2.118196361.1663591108.1493191643-1218444602.1483001627
在最后,我写下几点注意事项和情况。
初始场景(第一个场景,并不是从其他场景加载进来):
1.GameObject:enable 脚本:enable
正常执行 OnApplicationPause会在OnEnable下执行(一进入程序OnApplicationPause都会执行一次)
2.GameObject:enable 脚本:disable
Awake,OnApplicationPause
当脚本:enable 从OnEnable,Start正常执行下去
3.GameObject:disable 脚本:enable
不执行任何事件
当GameObject:enable 从Awake正常执行下去,但不会执行OnApplicationPause(因为不算第一次进入,第一次进入的时候已经disable了)
4.GameObject:disable 脚本:disable
不执行任何事件
当脚本:enable 不执行任何事件,因为GameObject是disable
当GameObject:enable && 脚本:disable 只执行Awake
当GameObject:enable && 脚本:enable 从Awake正常执行下去,但不会执行OnApplicationPause(因为不算第一次进入,第一次进入的时候已经disable了)
加载场景:
1.GameObject:enable 脚本:enable
正常执行 同上,但会在OnEnable后面执行OnLevelWasLoaded事件而不是OnApplicationPause(这里很明白了,因为不是第一次从外部进入本身程序)
2.GameObject:enable 脚本:disable
Awake,OnLevelWasLoaded
当脚本:enable 从OnEnable,Start正常执行下去
3.GameObject:disable 脚本:enable
不执行任何事件
当GameObject:enable 从Awake正常执行下去,但不会执行OnLevelWasLoaded(所以这个方法用起来用注意)
4.GameObject:disable 脚本:disable
不执行任何事件
当脚本:enable 不执行任何事件,因为GameObject是disable
当GameObject:enable && 脚本:disable 只执行Awake
当GameObject:enable && 脚本:enable 从Awake正常执行下去,但不会执行OnApplicationPause(因为不算第一次进入,第一次进入的时候已经disable了)
总的来说就是脚本所在的GameObject的enable和disable控制脚本的生命周期事件,两者的enable和disable的区别在于即使脚本是disable但GameObject是enable也能唤醒脚本的Awake事件。其余的OnApplicationPause还是按正常的逻辑可得知结果。而OnLevelWasLoaded方法则需要注意一些,从别的场景加载进来时候的GameObject是disable的话这个事件是不会被执行的。
还有一点,我们一般都是通过其他脚本Instantiate一些预制体。这些预制体一开始所在的GameObject是active的,也是就说一调用Instantiate创建的对象所在的脚本的Awake一定会被首先执行的。
这里还有一个注意点就是无论你在哪里开启了协程,只要GameObject或者脚本中途disable的话,这个协程就会停止掉,即使它是无限循环的。
因此想用好unity的生命周期的话,在一般的GameObject里,如果这个GameObject不会经常被enable和disable的话,可以按它的生命周期去写代码,如果是经常enable和disable的话(比如对象池中的对象),要在enable和disable中初始化或者重置对象的属性或者字段,Awake只做一些获取本身组件的执行。
备注:对于查找隐藏和非隐藏对象,可参考:http://www.xuanyusong.com/archives/2768