当前位置: 代码迷 >> 综合 >> 11-0002 Unity中函数的执行过程
  详细解决方案

11-0002 Unity中函数的执行过程

热度:55   发布时间:2023-11-24 01:55:12.0

事件功能的执行顺序

  • 1.脚本生命周期流程图
  • 2.函数调用流程
    • 2.1 First Scene Load
    • 2.2 Editor
    • 2.3 Before the first frame update
    • 2.4 In between frames
    • 2.5 Update order
    • 2.6 Animation update loop
    • 2.7 Useful profile markers
    • 2.8 Rendering
    • 2.9 Coroutines
    • 2.10 When the object is destroyed
    • 2.11 When quitting
  • 3.参考链接

1.脚本生命周期流程图

在这里插入图片描述

2.函数调用流程

2.1 First Scene Load

场景启动时会对场景中的每个对象执行一遍如下事件函数:

  • Awake: This function is always called before any Start functions and also just after a prefab
    is instantiated. (If a GameObject is inactive during start up Awake is not called until it is made active.)
  • OnEnable: (only called if the Object is active): This function is called just after the object is enabled. This happens when a MonoBehaviour instance is created, such as when a level is loaded or a GameObject
    with the script component is instantiated.
  • OnLevelWasLoaded: This function is executed to inform the game that a new level has been loaded.

  • Awake:游戏启动之前初始化任何变量和游戏状态,仅在脚本生命周期中调用一次,不能做协程,Start函数之前以及预制物体实例化后被调用。GameObject之间Awake的调用没有先后顺序规定,因而可以利用Awake建立脚本之间的引用,再使用Start 来回传递信息。(对于C#、Boo用户,当构造时组件序列化状态没有定义,就应该使用Awake代替构造函数初始化)。
  • OnEnable:只有GameObject是激活状态下才被调用,通常发生于MonoBehaviour实例被创建。

2.2 Editor

  • Reset: Reset is called to initialize the script’s properties when it is first attached to the object and also when the Reset command is used.

  • Reset:首次将脚本附加到对象以及使用“ Reset”命令时,将调用“Reset”以初始化脚本的属性。

2.3 Before the first frame update

  • Start: Start is called before the first frame update only if the script instance is enabled.

For objects added to the scene, the Start function will be called on all scripts before Update, etc are called for any of them. Naturally, this cannot be enforced when an object is instantiated during gameplay.


  • Start:仅在启用脚本实例的情况下,在第一帧更新之前调用Start。

对于添加到场景中的对象,将在Update之前在所有脚本上调用Start函数,等等。一般情况下,当在游戏过程中实例化对象时,不能强制执行此操作。

2.4 In between frames

  • OnApplicationPause: This is called at the end of the frame where the pause is detected, effectively between the normal frame updates. One extra frame will be issued after OnApplicationPause is called to allow the game to show graphics that indicate the paused state.

  • OnApplicationPause:这在检测到暂停的帧结束时调用,有效地在正常帧更新之间进行。在调用OnApplicationPause之后,将发出一帧额外的帧,以允许游戏显示指示暂停状态的图形。

2.5 Update order

When you’re keeping track of game logic and interactions, animations, camera positions, etc., there are a few different events you can use. The common pattern is to perform most tasks inside the Update function, but there are also other functions you can use.

  • FixedUpdate: FixedUpdate is often called more frequently than Update. It can be called multiple times per frame, if the frame rate is low and it may not be called between frames at all if the frame rate is high. All physics calculations and updates occur immediately after FixedUpdate. When applying movement calculations inside FixedUpdate, you do not need to multiply your values by Time.deltaTime. This is because FixedUpdate is called on a reliable timer, independent of the frame rate.
  • Update: Update is called once per frame. It is the main workhorse function for frame updates.
  • LateUpdate: LateUpdate is called once per frame, after Update has finished. Any calculations that are performed in Update will have completed when LateUpdate begins. A common use for LateUpdate would be a following third-person camera. If you make your character move and turn inside Update, you can perform all camera movement and rotation calculations in LateUpdate. This will ensure that the character has moved completely before the camera tracks its position.

当您跟踪游戏逻辑和互动,动画,摄像机位置等时,可以使用一些不同的事件。常见的模式是在Update函数中执行大多数任务,但是您还可以使用其他功能。

  • FixedUpdate: 与Update相比,FixedUpdate通常被更频繁地调用。如果帧速率低,则可以每帧多次调用它;如果帧速率高,则可以在帧之间根本不调用它。所有物理计算和更新都在FixedUpdate之后立即进行。在FixedUpdate中应用运动计算时,无需将值乘以Time.deltaTime。这是因为在可靠的计时器上调用了FixedUpdate,而与帧速率无关。
  • Update: 每帧调用一次更新。它是帧更新的主要功能。
  • LateUpdate: 更新完成后,每帧调用一次LateUpdate。LateUpdate开始时,Update中执行的所有计算都将完成。LateUpdate的常见用法是后续的第三人称相机。如果使角色移动并在Update内部旋转,则可以在LateUpdate中执行所有摄像机的移动和旋转计算。这将确保角色在摄像机跟踪其位置之前已完全移动。

2.6 Animation update loop

These functions and Profiler Markers are called when Unity evaluates the Animation system.

  • OnStateMachineEnter: During the State Machine Update step, this callback is called on the first update frame when a controller’s state machine makes a transition that flows through an Entry state. It is not called for a transition to a StateMachine sub-state.
    This callback occurs only if there is a controller component (for example, AnimatorController or AnimatorOverrideController or AnimatorControllerPlayable) in the animation graph.
    Note: Adding this callback to a StateMachineBehaviour component disables multithreaded state machine evaluation.
  • OnStateMachineExit: During the State Machine Update step, this callback is called on the last update frame when a controller’s state machine makes a transition that flows through an Exit state. It is not called for a transition to a StateMachine sub-state.
    This callback occurs only if there is a controller component (for example, AnimatorController or AnimatorOverrideController or AnimatorControllerPlayable) in the animation graph.
    Note: Adding this callback to a StateMachineBehaviour component disables multithreaded state machine evaluation.
  • Fire Animation Events: Calls all animation events from all clips sampled between the time of the last update and the time of the current update.
  • StateMachineBehaviour (OnStateEnter/OnStateUpdate/OnStateExit): A layer can have up to 3 active states: current state, interrupted state, and next state. This function is called for each active state with a StateMachineBehaviour component that defines the OnStateEnter, OnStateUpdate, or OnStateExit callback.
    The function is called for the current state first, then the interrupted state, and finally the next state.
    This step occurs only if there is a controller component (for example, AnimatorController or AnimatorOverrideController or AnimatorControllerPlayable) in the animation graph.
  • OnAnimatorMove: Every update frame, this is called once for each Animator component to modify the Root Motion.
  • StateMachineBehaviour(OnStateMove): This is called on each active state with a StateMachineBehaviour that defines this callback.
  • OnAnimatorIK: Sets up animation IK. This is called once for each Animator Controller layer with IK pass enabled.
    This event executes only if you are using a Humanoid rig.
  • StateMachineBehaviour(OnStateIK): This is called on each active state with a StateMachineBehaviour component that defines this callback on a layer with IK pass enabled.
  • WriteProperties: Writes all other animated properties to the Scene from the main thread.

当Unity评估动画系统时,将调用些功能和Profiler标记。

  • OnStateMachineEnter: 在状态机更新步骤中,当控制器的状态机进行流经Entry状态的转换时,将在第一个更新帧上调用此回调。它不要求过渡到StateMachine子状态。
    仅当动画图中存在控制器组件(例如AnimatorController或AnimatorOverrideController或AnimatorControllerPlayable)时,才发生此回调。
    Note: 将此回调添加到StateMachineBehaviour组件将禁用多线程状态机评估。
  • OnStateMachineExit: 在状态机更新步骤中,当控制器的状态机进行流经退出状态的转换时,将在最后一个更新帧上调用此回调。它不要求过渡到StateMachine子状态。
    仅当动画图中存在控制器组件(例如AnimatorController或AnimatorOverrideController或AnimatorControllerPlayable)时,才发生此回调。
    Note: 将此回调添加到StateMachineBehaviour组件将禁用多线程状态机评估。
  • Fire Animation Events: 从上次更新时间到当前更新时间之间采样的所有剪辑中调用所有动画事件。
  • StateMachineBehaviour (OnStateEnter/OnStateUpdate/OnStateExit): 一层最多可以具有3个活动状态:当前状态,中断状态和下一个状态。使用StateMachineBehaviour组件为每个活动状态调用此函数,该组件定义OnStateEnter,OnStateUpdate或OnStateExit回调。
    首先针对当前状态,随后的中断状态以及最后的下一个状态调用该函数。
    仅当动画图中存在控制器组件(例如AnimatorController或AnimatorOverrideController或AnimatorControllerPlayable)时,才发生此步骤。
  • OnAnimatorMove: 每个更新帧,每个Animator组件都会调用一次,以修改Root Motion。
  • StateMachineBehaviour(OnStateMove): 使用定义该回调的StateMachineBehaviour在每个活动状态上调用此方法。
  • OnAnimatorIK: 设置动画IK。启用IK传递的每个Animator Controller层都将调用一次。
    仅当您使用人形装备时,此事件才会执行。
  • StateMachineBehaviour(OnStateIK): 使用StateMachineBehaviour组件在每个活动状态上调用该组件,该组件在启用IK传递的层上定义此回调。
  • WriteProperties: 将所有其他动画属性从主线程写入场景。

2.7 Useful profile markers

Some of the animation functions shown in the Script Lifecycle Flowchart are not Event functions that you can call; they are internal functions called when Unity processes your animation.

These functions have Profiler Markers, so you can use the Profiler to see when in the frame Unity calls them. Knowing when Unity calls these functions can help you understand exactly when the Event functions you do call are executed.

For example, suppose you call Animator.Play in the FireAnimationEvents callback. If you know that the FireAnimationEvents callback is fired only after the State Machine Update and Process Graph functions execute, you can anticipate that your animation clip will play on the next frame, and not right away.

  • State Machine Update: All state machines are evaluated at this step in the execution sequence. This step occurs only if there is a controller component (for example, AnimatorController or AnimatorOverrideController or AnimatorControllerPlayable) in the animation graph.
    Note: State machine evaluation is normally multithreaded, but adding certain callbacks (for example OnStateMachineEnter and OnStateMachineExit) disables multithreading. See Animation update loop above for details.
  • ProcessGraph: Evaluates all animation graphs. This includes sampling all animation clips that need to be evaluated, and computing Root Motion.
  • ProcessAnimation: Blends the results of the animation graph.
  • WriteTransforms: Writes all animated transforms to the scene from a worker thread.
    A Humanoid rig with multiple layers that have IK pass enabled can have multiple WriteTransforms passes (See the Script Lifecycle Flowchart.

脚本生命周期流程图中显示的某些动画函数不是您可以调用的事件函数;它们是事件函数。它们是Unity处理动画时调用的内部函数。

这些功能具有Profiler标记,因此您可以使用Profiler来查看Unity在框架中何时调用它们。知道Unity何时调用这些函数可以帮助您准确地了解所调用的Event函数何时执行。

例如,假设您在FireAnimationEvents回调中调用Animator.Play()。如果您知道仅在执行“状态机更新”和“过程图”功能后才触发FireAnimationEvents回调,则可以预期动画剪辑将在下一帧播放,而不是立即播放。

  • State Machine Update: 在执行顺序的这一步,将评估所有状态机。仅当动画图中存在控制器组件(例如AnimatorController或AnimatorOverrideController或AnimatorControllerPlayable)时,才发生此步骤。
    Note: 状态机评估通常是多线程的,但是添加某些回调(例如OnStateMachineEnter和OnStateMachineExit)会禁用多线程。有关详细信息,请参见上面的动画更新循环。
  • ProcessGraph: 评估所有动画图。这包括对所有需要评估的动画剪辑进行采样,以及计算Root Motion。
  • ProcessAnimation: 混合动画图形的结果。
  • WriteTransforms: 将所有动画变换从辅助线程写入场景。
    具有启用了IK传递的多层的Humanoid装备可以具有多个WriteTransforms传递(请参阅脚本生命周期流程图)。

2.8 Rendering

  • OnPreCull: Called before the camera culls the scene. Culling determines which objects are visible to the camera. OnPreCull is called just before culling takes place.
  • OnBecameVisible/OnBecameInvisible: Called when an object becomes visible/invisible to any camera.
  • OnWillRenderObject: Called once for each camera if the object is visible.
  • OnPreRender: Called before the camera starts rendering the scene.
  • OnRenderObject: Called after all regular scene rendering is done. You can use GL class or Graphics.DrawMeshNow to draw custom geometry at this point.
  • OnPostRender: Called after a camera finishes rendering the scene.
  • OnRenderImage: Called after scene rendering is complete to allow post-processing of the image, see Post-processing Effects.
  • OnGUI: Called multiple times per frame in response to GUI events. The Layout and Repaint events are processed first, followed by a Layout and keyboard/mouse event for each input event.
  • OnDrawGizmos: Used for drawing Gizmos in the scene view for visualisation purposes.

  • OnPreCull: 在相机剔除场景之前调用。剔除确定相机可以看到哪些对象。在淘汰之前调用OnPreCull。
  • OnBecameVisible/OnBecameInvisible: 当对象对任何摄像机可见/不可见时调用。
  • OnWillRenderObject: 如果对象可见,则为每个摄像机调用一次。
  • OnPreRender: 在照相机开始渲染场景之前调用。
  • OnRenderObject: 在完成所有常规场景渲染之后调用。您可以在此时使用GL类或Graphics.DrawMeshNow绘制自定义几何。
  • OnPostRender: 在照相机完成场景渲染之后调用。
  • OnRenderImage:在场景渲染完成后调用,以允许对图像进行后期处理,请参阅后期处理效果。
  • OnGUI: 为响应GUI事件,每帧多次调用。首先处理Layout和Repaint事件,然后是每个输入事件的Layout和键盘/鼠标事件。
  • OnDrawGizmos: 用于在场景视图中绘制Gizmos,以实现可视化目的。

2.9 Coroutines

Normal coroutine updates are run after the Update function returns. A coroutine is a function that can suspend its execution (yield) until the given YieldInstruction finishes. Different uses of Coroutines:

  • yield: The coroutine will continue after all Update functions have been called on the next frame.
  • yield WaitForSeconds: Continue after a specified time delay, after all Update functions have been called for the frame
  • yield WaitForFixedUpdate: Continue after all FixedUpdate has been called on all scripts
  • yield WWW: Continue after a WWW download has completed.
  • yield StartCoroutine: Chains the coroutine, and will wait for the MyFunc coroutine to complete first.

在Update函数返回后,将运行常规协程更新。协程是可以暂停其执行(产量)直到给定的YieldInstruction结束的函数。协程的不同用途:

  • yield: 在下一帧调用所有Update函数之后,协程将继续。
  • yield WaitForSeconds: 在为帧调用了所有更新功能之后,在指定的时间延迟后继续。
  • yield WaitForFixedUpdate: 在所有脚本上调用所有FixedUpdate之后继续。
  • yield WWW: 在WWW下载完成后继续。
  • yield StartCoroutine: 链接协程,并将等待MyFunc协程首先完成。

2.10 When the object is destroyed

  • OnDestroy: This function is called after all frame updates for the last frame of the object’s existence (the object might be destroyed in response to Object.Destroy or at the closure of a scene).

  • OnDestroy: 在对对象存在的最后一帧进行所有帧更新后调用此函数(该对象可能会响应Object.Destroy或在场景关闭时被破坏)。

2.11 When quitting

These functions get called on all the active objects in your scene:

  • OnApplicationQuit: This function is called on all game objects before the application is quit. In the editor it is called when the user stops playmode.
  • OnDisable: This function is called when the behaviour becomes disabled or inactive.

这些功能在场景中的所有活动对象上调用:

  • OnApplicationQuit: 在退出应用程序之前,将在所有游戏对象上调用此函数。在编辑器中,当用户停止播放模式时将调用它。
  • OnDisable: 当行为变为禁用或不活动状态时,将调用此函数。

3.参考链接

Link:Order of Execution for Event Functions

  相关解决方案