Unity3D中脚本的生命周期是依照预先定义好的事件函数的运行流程来演化的,详细流程例如以下:
Editor模式下Reset:
当脚本第一次被挂到GameObject上或用户点击Resetbutton时,Reset被调用初始化脚本属性,最经常使用于在Inspector视图中呈现好的默认值。
载入第一个场景First Scene Load:
场景启动时会对场景中的每一个对象运行一遍例如以下事件函数:
- Awake:游戏启动之前初始化不论什么变量和游戏状态,仅在脚本生命周期中调用一次。不能做协程,Start函数之前以及预制物体实例化后被调用。
GameObject之间Awake的调用没有先后顺序规定,因而能够利用Awake建立脚本之间的引用。再使用Start 来回传递信息。(对于C#、Boo用户,当构造时组件序列化状态未定义,就应该使用Awake取代构造函数初始化)。
- OnEnable:仅仅有GameObject是激活状态下才被调用,通常发生于MonoBehaviour实例被创建。
第一帧更新之前Before the First Frame Update:
假设脚本实例化被启用,则Start函数在第一帧更新之前被调用。仅在脚本生命周期中调用一次。不论脚本enabled与否,Awake都会调用;假如初始化期间脚本disabled,则Start就不会与Awake在同一帧被调用。Awake和OnEnable一定是在Start之前调用(优点是:object A实例化代码依赖于object B实例化。B实例化就在Awake阶段完毕。A实例化就在Start阶段完毕)。
帧之间In Between Frames:
若暂停被检測到,当前帧运行后就调用OnApplicationPause函数,在正常的帧更新之间调用是有效的。在OnApplicationPause被调用后,添加额外的一帧来显示图像表明暂停状态。OnApplicationPause 能够是协程。假如其作为协程来运行。在初始化帧期间会被 用到两次:第一次用作前期通知,第二次发生在正常的协程更新步骤中。
更新顺序Update Order:
当想要追踪游戏逻辑、动画、相机位置等,能够在更新事件函数中运行这些任务,调用的顺序为FixedUpdate、Update、LateUpdate,当然脚本中不是必须三者都包括在内。三者不同见Unity3D的事件函数。
协程在全部Update函数完毕后运行。若在LateUpdate中开启了一个协程。它将在LateUpdate之后渲染之前也会被调用。
渲染Rendering:
- OnPreCull: 在相机剔除场景前被调用,剔除决定了哪些物体在相机中是可见的。
假如要改动相机的可视化參数(比方FOV,Transform等),就应该在这个函数中进行改动。此后场景中GameObject的可见性就取决于相机的參数了。
- OnBecameVisible/OnBecameInvisible:当GameObject在不论什么相机中变得可见/不可见时被调用。该消息被发送到不论什么挂在渲染器上的脚本。
使用这两个函数能够避免不必要的计算,仅当GameObject可见时才进行对应的计算。它们能够是协程,简单地使用yield 就可以,当在编辑器中运行时,场景视图摄像机也会导致它们被调用。
- OnWillRenderObject:假设物体可见而且脚本是enabled。在渲染每一个经过剔除操作之后的物体之前,它将为每一个相机调用一次。
- OnPreRender:仅当脚本挂在相机上而且enabled时,则在相机開始渲染场景之前被调用。
假如在这个函数中改动了相机的可视化參数(比方FOV)。那么这些參数仅仅会在下一帧中起到作用。
该函数能够是协程。仅在函数中使用yield就可以。
- OnRenderObject:在全部固定场景渲染之后被调用。此时你能够使用GL类函数或者Graphics.DrawMeshNow来画自己定义的几何体。
该函数和OnPostRender相似。除了一点:不论脚本挂在相机上与否。OnRenderObject都会在不论什么GameO上被调用。
- OnPostRender:在相机完毕场景的渲染后被调用。与OnRenderObject不同,仅当脚本挂在相机上而且是enabled时,该函数才会被调用。
假如想要在全部相机和GUI渲染之后做操作,使用
WaitForEndOfFrame协程。 - OnRenderImage(Pro only):在场景渲染完毕后被调用,用于对屏幕的图像进行后处理,该消息被发送到挂到相机上的全部脚本。该函数同意利用基于shader的过滤器对终于图像进行处理。传入源渲染纹理。终止于目标渲染纹理;当相机有多个图像过滤器时,图像顺序被处理,前一个过滤器的目标渲染纹理作为下一个过滤器的源渲染纹理。
- OnGUI:为响应GUI事件,该函数每帧被调用多次,每一个事件就调用一次;运行时先响应布局和重绘事件,随后是为每一次的输入事件运行布局和键盘/鼠标事件。
- OnDrawGizmos:为了可视化的目的,从而在场景视图中绘制小图标。该函数使用相对于Scene视图的鼠标的位置,同意高速挑选场景中重要的GameObject,当然假如组件在inspector中collapsed,则该函数就不会被调用。
协程Coroutines:
正常情况下协程是在Update函数返回时运行。协程的功能是。延缓其运行(yield) ,直到给定的YieldInstruction完毕。协程的不同用途:
- yield:协程在全部的Update函数在下一帧被调用后继续运行。
- yield WaitForSeconds:在一个指定的时间延迟后继续运行,在该帧全部的Update函数被调用之后,仅可用于协程中的yield语句。
- yield WaitForFIexedUpdate:在全部脚本上全部的FixedUpdate被调用之后继续运行,就可以用于协程中的yield语句。
- yield WWW:在WWW载入完毕之后继续运行。
- yield StartCoroutine:等待MyFunc协程先完毕。用于链接协程。该函数总是会马上返回,然而能够yield结果,这样就就会等到协程完毕运行然后返回。使用JavaScript不必使用该函数,由于编译器会为你做这个工作。若使用C# 就需使用该函数了。
对象被销毁时When the Object is Destroyed:
OnDestroy这个函数在全部帧更新之后被调用。在对象存在的最后一帧中(对象被销毁来响应Object.Destroy或关闭一个场景)。该函数不能够是协程。
当退出时When Quitting:
对于场景中全部active对象都会调用下列函数:
- OnApplicationQuit:在应用退出之前全部的游戏对象都会调用该函数。在编辑器中当用户停止播放时它将被调用;在webplayer中。当网页关闭时被调用。
- OnDisable:当行为不可用或非激活时。该函数被调用。
当对象被销毁时。或对于不论什么清理工作的代码。该函数相同可被调用。
当编译完毕之后又一次载入脚本,该函数可被调用,紧随其后脚本载入完毕时调用OnEnable。
脚本生命周期流程图:
综上所述,关于脚本整个生命周期可參见unity3d脚本生命周期流程图。