事件函数的运行顺序
Unity 脚本中有很多按预设顺序以脚本身份执行的事件函数。
其执行顺序例如以下:
载入第一个场景
启动场景时调用这些函数(为场景中的每一个对象调用一次)。
-
Awake: 始终在调用不论什么 Start 函数之前和实例化预设之后调用此函数。
(假设游戏对象 (GameObject) 在启动期间处于非活动状态,则直到其处于活动状态时或调用加入至其本身的不论什么脚本中的函数时,再调用 Awake 函数。
)
-
OnEnable: (仅当对象 (Object) 处于活动状态时调用此函数):程序会在启用该对象后马上调用此函数。
上述现象会在创建了实例化的 MonoBehaviour 后发生,比如载入了级别或对含脚本组件的游戏对象 (GameObject) 进行实例化后。
第一帧更新之前
- Start: 仅仅要启用脚本实例,就可以在更新第一帧之前调用 Start 函数。
插值帧
-
OnApplicationPause: 程序检測到暂停时,会在帧的结尾处调用此函数,这在常规帧更新期间非常有效。调用
OnApplicationPause后,程序将执行还有一帧来显示提示暂停状态的图形。
更新顺序
有几个不同的事件有助于追踪游戏逻辑与交互、动画、相机位置等内容。
经常使用的方法是执行Update() 函数中的大部分任务。但也可使用其它函数。.
-
FixedUpdate: 通常,FixedUpdate() 的调用频率高于Update()。假设帧速率较低,则可在一帧中多次调用此函数,假设帧速率较高,则可能全然无法在帧间调用此函数。
程序调用FixedUpdate() 后将马上运行全部物理计算和更新。在FixedUpdate()
中应用移动计算时。无需将您的值与 Time.deltaTime 相乘。这是由于。程序是在可靠的计时器上调用FixedUpdate(),与帧速率无关。
- Update: 在每帧上调用一次 Update() 函数。它是用于帧更新的主要 workhorse 函数。
-
LateUpdate: 完毕 Update() 调用后。在每帧上调用LateUpdate()。
Update() 中运行的全部计算都将在LateUpdate() 開始之前结束。LateUpdate()
的常规使用记录由第三人称相机跟踪。假设在Update() 中移动和旋转角色,则可在
LateUpdate() 中计算全部相机移动和旋转。这将确保在相机跟踪其位置之前完整移动该角色。
渲染
-
OnPreCull: 在相机剔除场景之前调用此函数。相机可见的对象取决于剔除。
OnPreCull 函数调用发生在剔除之前。
- OnBecameVisible/OnBecameInvisible: 在对象对于相机可见/不可见时调用此函数。
- OnWillRenderObject: 假设对象可见。则为每一个相机调用一次此函数。
- OnPreRender: 在相机開始渲染场景之前调用此函数。
- OnRenderObject: 在完毕全部常规场景渲染后调用此函数。此时,可使用 GL 类或 Graphics.DrawMeshNow 绘制自己定义几何图形。
- OnPostRender: 在相机完毕场景渲染后调用此函数。
- OnRenderImage(仅限专业版): 在完毕场景渲染后调用此函数。以便对屏幕图像进行后处理。
-
OnGUI: 在每帧上多次调用此函数,以响应 GUI 事件。
程序首先将处理 Layout 和 Repaint 事件。然后再处理每一个输入事件的 Layout 和 keyboard/鼠标事件。
- OnDrawGizmos 用于在场景视图中绘制小图示 (Gizmos)。以实现可视化目的。
协同程序
正常的协同程序更新是在返回 Update 函数之后执行。
协同程序是可自行停止执行 (yield),直到给定的 YieldInstruction 结束再继续执行的函数。协同程序 (Coroutines) 的不同用途:
- yield; 在下一帧上调用全部 Update 函数后,协同程序将继续执行。
- yield WaitForSeconds(2); 在指定的时间延迟之后,为此帧调用全部 Update 函数之后继续执行
- yield WaitForFixedUpdate(); 在全部脚本上调用全部 FixedUpdate 后继续执行
- yield WWW 完毕 WWW 下载后继续执行。
- yield StartCoroutine(MyFunc); 连接协同程序,并等待 MyFunc coroutine 首先结束。
对象 (Object) 被销毁时
- OnDestroy: 完毕全部帧更新后,在当前对象的最后一帧上调用此函数(可能为响应 Object.Destroy 或在关闭场景时销毁此对象)。
退出时
程序将在场景的全部活动对象上调用这些函数:
-
OnApplicationQuit: 在退出应用程序之前,程序会在全部游戏对象上调用此函数。
在编辑器中。用户停止播放模式时,程序将调用此函数。
在网页播放器中。此函数会在网页视图关闭时调用。
- OnDisable: 此函数会在行为被禁用或不活动时调用。
综上所述。不论什么给定脚本的运行顺序为:
- 调用全部 Awake
- 调用全部 Start
-
同一时候进行(朝向可变增量时间)
- 全部 FixedUpdate 函数
- 物理模拟
- OnEnter/Exit/Stay 触发函数
- OnEnter/Exit/Stay 碰撞函数
- 刚体插值应用 transform.position 和旋转
- OnMouseDown/OnMouseUp 等事件
- 全部 Update 函数
- 将动画优化为高级、混合并应用动画,以进行变换
- 全部 LateUpdate 函数
- 渲染
提示
- 协同程序在全部 Update 函数结束后执行。
-
脚本的生命周期流程图
vital.png
在Unity3D脚本中,有几个Unity3D自带的事件函数依照预定的顺序运行作为脚本运行。其运行顺序例如以下:
编辑器(Editor)
-
Reset:Reset函数被调用来初始化脚本属性当脚本第一次被附到对象上。而且在Reset命令被使用时也会调用。
编者注:Reset是在用户点击Inspector面板上Resetbutton或者首次加入该组件时被调用。Reset最经常使用于在见识面板中给定一个默认值。
第一次场景载入(First Scene Load)
这些函数会在一个场景開始(场景中每一个物体仅仅调用一次)时被调用。
- Awake:这个函数总是在不论什么Start()函数之前一个预设被实例化之后被调用。假设一个GameObject是非激活的(inactive),在启动期间Awake函数是不会被调用的直到它是活动的(active)。
- OnEnable:仅仅有在对象是激活(active)状态下才会被调用,这个函数仅仅有在object被启用(enable)后才会调用。这会发生在一个MonoBehaviour实例被创建。比如当一个关卡被载入或者一个带有脚本组件的GameObject被实例化。
注意:当一个场景被加入到场景中,全部脚本上的Awake()和OnEable()函数将会被调用在Start()、Update()等它们中不论什么函数被调用之前。自然的,当一个物体在游戏过程中被实例化时这不能被强制运行。
第一帧更新之前(Before the first frame update)
- Start:仅仅要脚本实例被启用了Start()函数将会在Update()函数第一帧之前被调用。
对于那些被加入到场景中的物体,全部脚本上的Start()函数将会在它们中不论什么的Update()函数之前被调用,自然的,当一个物体在游戏过程中被实例化时这不能被强制运行。
在帧之间(In between frames)
- OnApplicationPause:这个函数将会被调用在暂停被检測有效的在正常的帧更新之间的一帧的结束时。在OnApplicationPause被调用后将会有额外的一帧用来同意游戏显示显示图像表示在暂停状态下。
更新顺序(Update Order)
当你在跟踪游戏逻辑和状态。动画,相机位置等的时候。有几个不同的事件函数你能够使用。
常见的模式是在Update()函数中运行大多数任务,可是也有其他的函数你能够使用。
- FixedUpdate:FixedUpdate函数经常会比Update函数更频繁的被调用。它一帧会被调用多次,假设帧率低它可能不会在帧之间被调用,就算帧率是高的。全部的图形计算和更新在FixedUpdate之后会马上运行。当在FixedUpdate里运行移动计算。你并不须要Time.deltaTime乘以你的值。这是由于FixedUpdate是按真实时间,独立于帧率被调用的。
- Update:Update每一帧都会被调用,对于帧更新它是基本的负荷函数。
-
LateUpdate:LateUpdate会在Update结束之后每一帧被调用,不论什么计算在Update里运行结束当LateUpdate開始时。
LateUpdate经常使用为第三人称视角相机尾随。
渲染(Rendering)
-
OnPreCull:在相机剔除场景前被调用。
剔除是取决于哪些物体对于摄像机是可见的。OnPreCull仅在剔除起作用之前被调用。
- OnBecameVisible/OnBecameInvisible:当一个物体对随意摄像机变得可见/不可见时被调用。
- OnPreRender:在摄像机開始渲染场景之前调用。
- OnRenderObject:在指定场景渲染完毕之后调用。你能够使用GL类或者Graphics.DrawMeshNow 来绘制自己定义几何体在这里。
- OnPostRender:在摄像机完毕场景渲染之后调用。
- OnRenderImage(Pro Only):在场景徐然完毕之后同意屏幕图像后期处理调用。
-
OnGUI:为了响应GUI事件,每帧会被调用多次(一般最低两次)。布局Layout和Repaint事件会首先处理,接下来处理的是是通过
Layout和键盘/鼠标事件相应的每一个输入事件。 - OnDrawGizmos:用于可视化的绘制一些小玩意在场景视图中。
协同程序(Coroutines)
正常的协同程序更新是在Update函数返回之后执行。
一个协同程序是能够暂停执行(yield)直到给出的依从指令(YieldInstruction )完毕。写成的不同运用:
- yield:在全部的Update函数都已经被调用的下一帧该协程将持续运行。
- yield WaitForSeconds:一段指定的时间延迟之后继续运行,在全部的Update函数完毕调用的那一帧之后。
- yield WaitForFixedUpdate:全部脚本上的FixedUpdate函数已经运行调用之后持续。
- yield WWW:在WWW下载完毕之后持续。
- yield StartCoroutine:协同程序链。将会等到MuFunc函数协程运行完毕首先。
销毁(When the Object is Destroyed)
- OnDestory:这个函数在会在一个对象销毁前一帧调用,会在全部帧更新一个对象存在的最后一帧之后运行,对象或许会响应Object.Destroy 或一个场景关闭时被销毁。
退出游戏(When Quitting)
这些函数会在你场景中全部的激活的物体上调用:
- OnApplicationQuit:这个函数在应用退出之前的全部游戏物体上调用,在编辑器(Editor)模式中会在用户停止PlayMode时调用。在网页播放器(web player)中会在网页视图关闭时调用。
- OnDisable:当行为变为非启用(disable)或非激活(inactive)时调用。