Untiy3D函数生命周期详解
常用函数执行顺序
Awake --> OnEnble --> Start --> FixedUpdate --> Update --> LateUpdate --> OnGUI --> OnDisable -->OnDestroy
编辑器(Editor)
Reset:当脚本第一次附加到对象以及当使用Reset命令时,都会调用Reset来初始化脚本的属性。(Reset是在用户点击Inspector面板上Reset按钮或首次添加该组件时被调用。Reset最常用于在Inspector面板中给定一个默认值。)
第一次场景加载(First Scene Load)
这些函数在场景启动时调用(对于场景中的每个对象只调用一次)。
Awake:这个函数总是在Start函数之前调用,并且在所以对象实例化之后调用。(如果游戏对象在启动时处于非活动状态,直到**后才调用。也就是说当游戏对象处在活动状态,脚本处在非活动状态,也会调用这个函数。)
OnEnable:仅在对象处于活动状态时调用,此函数在对象启用后调用。(当一个MonoBehaviour实例被创建时,例如当一个关卡被加载或带有脚本组件的GameObject被实例化时)
OnLevelWasLoaded:这个函数是为了通知游戏一个新的关卡已经被载入。(对于添加到场景中的对象,所有脚本的Awake和OnEnable函数将在Start、Update等之前被调用。)
第一帧更新之前(Before the first frame update)
Start:只有在启用脚本实例时,才在Update函数执行第一帧之前调用。(对于添加到场景中的对象,在更新之前会对所有脚本调用Start函数)
在帧之间(In between frames)
OnApplicationPause:在检测到暂停时会在帧的末尾调用,在正常的帧更新之间有效。(在OnApplicationPause被调用后,将会有额外的一帧来允许游戏显示图像表示在暂停状态下。可以适用于游戏被强制暂停的判断和处理)
更新顺序(Update Order)
当你在跟踪游戏逻辑和状态,动画,相机位置等的时候,有几个不同的事件函数你可以使用。常见的模式是在Update函数中执行大多数任务,但是也有其它的函数你可以使用。
FixedUpdate:固定更新帧,更新频率默认为0.02s。这个函数通常比Update调用更频繁。如果帧速率低,则可以在每帧中调用多次,如果帧速率高,则根本不能在帧之间调用。(所有物理计算和更新在FixedUpdate之后立即发生。在FixedUpdate中应用移动计算时,不需要将值乘以Time.deltaTime。这是因为FixedUpdate是在一个独立于帧速率的可靠定时器上调用的。)
设置FixedUpdate更新频率:在Unity导航菜单栏中,点击“Edit”-->“Project Setting”-->“Time”菜单项,右侧的Inspector视图弹出TimeManager,在“Fixed Timestep”中输入所需更新频率。
Update:正常帧更新,每一帧调用一次。它是帧更新的主要工作函数。
Update与FixedUpdate的区别:Update会在每次渲染新的一帧时被调用。而FixedUpdate会在每个固定的时间间隔被调用。(Update受当前渲染的物体,更确切的说是三角形的数量影响,帧率会发生变化,Update被调用的时间间隔就发生变化。但是FixedUpdate则不受帧率的变化,它是以固定的时间间隔来被调用。)
LateUpdate:在Update完成后,每帧调用一次LateUpdate。(在Update中执行的任何计算都将在LateUpdate开始时完成。常用于第三人称视角相机跟随。)
Update和LateUpdate的区别:LateUpdate在所有Update函数结束后被调用。这可用于调整脚本执行顺序。(有两个脚本,一个脚本里有只有Update 函数,另外一个脚本里有Update 和LateUpdate 函数。LateUpdate要等两个脚本中的Update 函数都执行完才会执行。无论有多少个Update 都得等Update 执行完再执行LateUpdate函数)
案例:假设有2个不同的脚本同时在Update中控制一个物体,那么当其中一个脚本改变物体方位、旋转或者其他参数时,另一个脚步也在改变这些东西,那么这个物体的方位、旋转就会出现一定的反复。如果还有个物体在Update中跟随这个物体移动、旋转的话,那跟随的物体就会出现抖动。 如果是在LateUpdate中跟随的话就会只跟随所有Update执行完后的最后位置、旋转,这样就防止了抖动。
渲染(Rendering)
OnPreCull:在相机剔除场景前调用。剔除时取决于那些物体对于相机是可见的,仅在剔除起作用前调用。
OnBecameVisible/OnBecameInvisible:当一个物体对任意摄像机可见/不可见时调用
OnWillRenderObject:如果对象可见,则对每个摄像机调用一次。
OnPreRender:在摄像机开始渲染场景之前调用。
OnRenderObject:在指定场景渲染完成之后调用。你可以使用GL类或Graphics.DrawMeshNow在这里绘制自定义几何体。
OnPostRender:在摄像机完成场景渲染后调用。
OnRenderImage:在场景渲染完成后调用,允许对图像进行后期处理,查看后期处理效果。
OnGUI:响应GUI事件,每帧调用多次。(先处理Layout和Repaint事件,然后处理每个输入事件和键盘/鼠标对应的每个输入事件。)
OnDrawGizmos:用于可视化的绘制一些小东西在场景视图中。
协同程序(Coroutines)
正常的协同程序更新是在Update函数返回之后运行。协程是一个函数,它可以在给定的YieldInstruction完成之前暂停其执行(yield)。
yield:在所有的Update函数都已经被调用后,协同程序将继续执行。
yield WaitForSeconds:在指定的时间延迟之后继续执行,在所有Update函数完成调用的那一帧之后。
yield WaitForFixedUpdate:在所有脚本上的FixedUpdate函数调用之后继续执行。
yield WWW:WWW下载完成后继续执行。
yield StartCoroutine:协同程序链,将等待MyFunc协同程序来完成首先。
当对象被销毁时(When the Object is Destroyed)
OnDestroy:在对象存在的最后一帧更新所有帧之后调用这个函数。(对象可能会响应Object.Destroy或一个场景关闭时被销毁)。
退出游戏(When Quitting)
这些函数会在你场景中的所有活动对象上调用
OnApplicationQuit:这个函数在应用程序退出之前在所有游戏对象上调用。在编辑器中,用户停止PlayMode时调用。
OnDisable:当行为禁用或不活动时调用此函数。也就是对象或者脚本变为非活动状态调用这个函数
脚本生命周期流程图
下图总结了脚本生命周期中事件函数的顺序和重复。
Unity3D脚本手册事件函数的执行顺序https://docs.unity3d.com/Manual/ExecutionOrder.html
引用文章
https://blog.csdn.net/gtncwy/article/details/44752703