Unity-MonoBehaviour运行周期

作者: ZeroTryTryTry | 来源:发表于2018-03-08 23:32 被阅读20次

    MonoBehaviour是Unity中非常重要的一个类,游戏逻辑、资源管理以及画面渲染等都离不开这个类。MonoBehaviour为我们提供了许多的内置函数来实现我们的各种需要。例如AwakeStartUpdate等都是常见的函数,下面会介绍各个重要函数以及其在整个运行周期里的功能。根据不同函数调用次数可以分为:

    只调用一次的函数

    Awake

    Awake函数在脚本实例加载时调用

    Start

    Update函数第一次被调用前调用

    根据情况触发的函数

    OnEnable

    当MonoBehaviour的状态变为enabled时触发

    OnDisable

    当MonoBehaviour的状态变为disabled时触发

    OnBecameVisible

    当MonoBehaviour附加的渲染器被任何的Camera视为可见时触发

    OnBecameInvisible

    当MonoBehaviour附加的渲染器被任何的Camera视为不可见时触发

    OnDestroy

    当MonoBehaviour即将被销毁时触发

    OnLevelWasLoaded

    当新关卡被载入时触发

    会定时调用的函数

    FixedUpdate

    当MonoBehaviour处于enabled状态时,间隔指定的时间调用

    Update

    当MonoBehaviour处于enabled状态时,每帧调用

    LateUpdate

    当MonoBehaviour处于enabled状态时,在所有Update函数调用后被调用

    重要函数执行顺序

    一个对象创建过程

    接下来分析下几个重要函数在一个对象的执行顺序,在开发过程中比较常见的有:Awake, OnEnable, Start, Update, LateUpdate.先用一个脚本ScriptA测试一下。

    using UnityEngine;
    using System.Collections;
    
    public class ScriptA : MonoBehaviour {
    
        void Awake()
        {
            Debug.Log("Awake");
        }
    
        void Start () {
            Debug.Log("Start");
        }
    
        void OnEnable()
        {
            Debug.Log("OnEnable");
        }
        
        void Update ()
        {
            Debug.Log("Update");
        }
    
        void LateUpdate()
        {
            Debug.Log("Late Update");
        }
    }
    

    执行结果如下图:


    常用函数执行顺序

    从图中可以看到脚本是按着这样的顺序执行的:Awake->OnEnable->Start->Update->LateUpdate.

    多个对象创建过程

    接下来创建两个物体GameObject A 和 GameObject B,都挂上之前的ScriptA脚本(在函数中打印物体的名字)。然后Play。结果如下:


    多个对象的情况

    从结果可以看到GameObject B在 执行完AwakeOnEnable后才执行GameObjectA的AwakeOnEnable函数。
    这里主要的原因是Unity在初始化实例时会先调用Awake然后若实例为Enable则紧接着调用该实例的OnEnable方法,接着就是执行别的实例的Awake方法及其OnEnable方法。

    多个对象销毁过程

    将ScriptA改为如下:

    using UnityEngine;
    using System.Collections;
    
    public class ScriptA : MonoBehaviour {
    
        void Awake()
        {
            Debug.Log("Awake:" + gameObject.name);
        }
    
        void Start () {
            Debug.Log("Start:" + gameObject.name);
    
            Debug.Log("Destroy GameObject~");
    
            Destroy(gameObject);
        }
    
        void OnEnable()
        {
            Debug.Log("OnEnable:" + gameObject.name);
        }
    
        void OnDisable()
        {
            Debug.Log("OnDisable: " + gameObject.name);
        }
    
        void OnDestroy()
        {
            Debug.Log("OnDestroy: " + gameObject.name);
        }
    }
    

    然后执行后得到以下结果:


    多个对象销毁过程

    高亮部分对GameObject B进行了Destroy操作,可以看到调用后立刻执行了GameObject B的OnDisable函数。之后才执行GameObject A的Start函数。最后执行OnDestroy函数。销毁时: OnDisable->OnDestroy

    从以上结果可以看出OnEnable/OnDisable函数在实例实例创建后会即刻执行(OnEnable是在Awake后执行)。

    多个脚本的执行情况

    对于多个脚本如果在未指定Execution Order的情况下执行顺序是随机的,我们可以在Edit->Project Setting->Script Execution Order窗体中进行设置,值越小,越先执行。(从脚本的Inspector界面里面的Execution Order也可以打开)

    通过Inspector打开

    通过设置脚本的顺序值就可以达到控制脚本执行顺序的作用,如图中我们给ScriptA设置了100,给ScriptB设置了200.


    设置脚本的顺序值

    接下来编写简单的脚本的执行情况:


    ScriptA先于ScriptB执行

    相关文章

      网友评论

        本文标题:Unity-MonoBehaviour运行周期

        本文链接:https://www.haomeiwen.com/subject/bipdtftx.html