Unity 生命周期

最近做项目,碰到当一个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

posted on 2017-04-26 17:37  爱裸奔的小亮亮  阅读(419)  评论(0编辑  收藏  举报

导航