Script Lifecycle要编写出好的Unity脚本,就必须充分理解脚本的生命周期,也就是各个模块流程的执行模式。本文将对Unity脚本的生命周期流程图进行较为深入的解读。主要部分参考官方文档,附带一些博客的深入解释。
概述
Unity脚本执行顺序是有严格规定的,这些规定的目的是使得3D游戏应用开发更加方便。因此,熟悉脚本生命周期是非常有必要的。
以上是对单个脚本内各个方法调用的执行顺序,除此之外,Unity还支持更加高端的多个脚本间自定义脚本执行顺序功能,可以自定义修改脚本执行顺序。
场景的初次加载
当场景开始加载时这些函数会被调用(场景中每个物体只调用一次)。
- Awake:这个函数总是优先于任何Start 函数加载并且滞后于实体的生成。(如果一个物体是inactive 状态,那么Awake 不会执行。)
- OnEnable:这个函数在实体处于enable 状态之后执行。(如果一个物体是inactive 状态,那么OnEnable 不会执行。)
- OnLevelWasLoaded:新场景加载时执行此函数。
注意:当场景中加入实体的时候,Awake 和OnEnable 总是优先于其余函数执行(也就是说等所有实体的这两个函数执行完之后,才会轮到各个实体的Start 执行)。自然地,当处于游戏过程中的时候,新物体的加入也会按照这个规则执行,只是由于之前Start 已经执行而没办法保证在所有Start 函数之前。
在第一帧更新之前
- Start:这个函数在第一帧更新之前调用且实体处于enable 状态下。(特定实体的特定脚本只会Start 一次。)
处于帧之间
- OnApplicationPause:当收到暂停指令后,这个函数会在当前帧的最后触发。这个时候,函数会显示额外的一帧图像以代表暂停状态。
更新顺序
- FixedUpdate:这个函数的更新频率与帧率无关,他的调用频率只与稳定的时钟有关,可以作为物理量更新的入口。且内部的量不需要乘上Time.deltaTime(已经默认乘过了)。
- Update:跟帧率同步更新。
- LateUpdate:跟帧率同步更新,这个函数总是在Update 全部完成之后再更新。比如:当你设计第三人称游戏人物时,可以将人物的动作更新放在Update 里,而将跟随相机的运动放在LateUpdate 里,这样可以保证监视人物运动的稳定性,不至于产生眩晕抖动的效果。
渲染
渲染过程很重要,主要涉及背景剔除前后、渲染前后等步骤。这里不展开讲,各个回调函数名称基本就能解释清楚了。
- OnGUI:跟帧率无关,布局和重绘处理在先,键盘、鼠标等输入处理在后。也就是说,输入响应也是在OnGUI 里面实现的。
协程
协程的作用是延缓程序的执行直到等待指令完成,这是一种轻量级非阻塞异步并发方式,一般用于Update 函数返回之后。同时,函数内部的协程等待时,并不会堵塞外部函数的执行。主要用法有以下几种:
- yield:协程将会在下一帧所有Update 函数执行完成之后执行。
- yield WaitForSeconds:在特定时间间隔后执行,在本帧所有Update 函数执行之后执行。
- yield WaitForFixedUpdate:在所有脚本的FixedUpdate 调用之后执行。
- yield WWW:在一个WWW 链接下载完成之后执行。
- yield StartCoroutine:将多个协程串起来,并且会让本协程优先完成。
初始化顺序
如果对执行顺序有疑问的可以使用 文献资源6 中的脚本进行自主测试。下文的总结均为实测结果。
- 实体优先于脚本,且默认初始化顺序按照挂载顺序从下到上;此时脚本默认初始化顺序也是按照挂载顺序从下到上。
- 若定制化脚本顺序则脚本优先于实体,定制化方法按照设定执行时间轴由小到大执行。
网友评论