首页 理论教育带你领略虚拟现实应用实践!

带你领略虚拟现实应用实践!

【摘要】:而MonoBehaviour是Unity中所有脚本的基类,如果使用JS的话,脚本会自动继承MonoBehaviour。如果使用C#的话,需要显式继承MonoBehaviour。OnDestroy:当MonoBehaviour将被销毁时,这个函数被调用。接下来,先看一下,关于MonoBehavior这个类的继承关系。所以综上MonoBehaviour的作用就是开发者可以自定义自己的组件类。图7-56就是MonoBehaviour的生命周期流程。图7-56MonoBehaviour的生命周期流程我们主要关心的是在运行状态,因为此时脚本的生命周期真正开始,如图7-57所示。

Unity面向组件开发,游戏物体想要实现什么样的功能,只需要添加相对应的组件就可以了,此时会在属性面板上显示出来。可以像添加组件一样把脚本添加到游戏物体上。而MonoBehaviour是Unity中所有脚本的基类,如果使用JS的话,脚本会自动继承MonoBehaviour。如果使用C#的话,需要显式继承MonoBehaviour。

在使用MonoBehaviour的时候,需要注意有哪些可重写函数,这些可重写函数会在游戏中发生某些事件的时候被调用。在Unity中最常用到的几个可重写函数是这几个:

(1)Awake:当一个脚本实例被载入时Awake被调用。我们大多在这个类中完成成员变量初始化

(2)OnEnable:当对象变为可用或激活状态时此函数被调用。

(3)Start:仅在Update函数第一次被调用前调用。因为它是在Awake之后被调用的,我们可以把一些需要依赖Awake的变量放在Start里面初始化。同时我们还大多在这个类中执行StartCoroutine进行一些协程的触发。要注意在用C#写脚本时,必须使用StartCoroutine开始一个协程,但是如果使用的是JavaScript,则不需要这么做。

(4)Update:当MonoBehaviour启用时,其Update在每一帧被调用。

(5)FixedUpdate:当MonoBehaviour启用时,其FixedUpdate在每一固定帧被调用。

(6)LateUpdat方法:是在所有Update函数调用后被调用。这可用于调整脚本执行顺序。例如:当物体在Update里移动时,跟随物体的相机可以在LateUpdate里实现。

(7)OnGUI方法:渲染和处理GUI事件时调用(注意:这里不是每帧都调用)

(8)OnDisable:当对象变为不可用或非激活状态时此函数被调用。

(9)OnDestroy:当MonoBehaviour将被销毁时,这个函数被调用。

接下来,先看一下,关于MonoBehavior这个类的继承关系(见图7-55)。

从图7-55可以看出,MonoBehaviour是间接继承自Component,说明继承自MonoBehaviour的脚本充当的角色是组件的角色,当我们需要将一个自定义脚本以组件的形式添加到对应的GameObject时,该脚本是必须要继承MonoBehaviour。所以综上MonoBehaviour的作用就是开发者可以自定义自己的组件类。

当我们拥有自己的组件类时,我们会对类的生命周期,和一些重要的接口感兴趣,以便在使用过程中,不那么疑惑。图7-56就是MonoBehaviour的生命周期流程。

图7-55 关于MonoBehavior这个类的继承关系

首先我们可以将这张图分成两种状态:

(1)编辑器下的状态:可以单击设置,Reset函数,将脚本恢复默认状态。

(2)运行状态(真正的生命周期):除Reset函数外,其余函数都在运行状态执行(加特殊字段,该脚本也可已在编辑器运行)。

图7-56 MonoBehaviour的生命周期流程

我们主要关心的是在运行状态,因为此时脚本的生命周期真正开始,如图7-57所示。

图7-57 运行模式状态

当单击Unity3D的Play按钮时,脚本会从编辑器模式进入运行模式,会先走Initialization步骤,从名字可以看出,该步骤做的是初始化操作,且确定了三个函数的调用时序。那么三个函数有什么区别呢:

(1)Awake。调用条件:gameObj is Active(场景开始时当前obj的Active是true)或者在Instantiate一个Prefab之后。(www.chuimin.cn)

注意:总是在所有脚本调用Start之前调用,如7-58所示。

图7-58 Awake调用

Awake函数只调用一次。

(2)OnEnable。调用条件:当执行完Active时。

注意事项:将enable=false,会在执行完OnEnable后,直接执行OnDisable,在OnDisable设置enable=true就会跳到OnEnable(切记不要出现死循环)。

(3)Start。调用条件:OnEnable执行完。

注意事项:Start只会执行一次,无论下次第几次调用到OnEnable,均不会在执行(适合初始化)。

上述是生命周期的开始,这里暂时不讲生命周期运行,直接将生命周期的结束,如图7-59所示。

图7-59 生命周期的结束

OnApplicationQuit:当应用程序退出时,会先调用OnApplicationQuit(可以在此时来save你的数据)。

OnDisable:除在OnApplicationQuit调用时会调用,还会再设置enable=false或active=false调用。

OnDestory:除在OnApplicationQuit调用时会调用,还有在手动的Destory gameObject时。

讲完了生命周期的开始和结束,接下来介绍最重要的部分,如图7-60所示。

图7-60 生命周期的中间部分

上述有很多Update和很多yield,可以从上述看到三个Update调用的顺序,FixedUpdate→Update→LateUpdate,如图7-61所示。

由此可见,Unity是调用完所有脚本的FixedUpdate,在调用所有脚本的Update,在调用所有脚本的LateUpdate。

关于协程中的yield其实很好理解,如图7-62所示。

图7-61 Update调用的顺序

图7-62 协程中的yield

比如yield null,表示当函数运行到此处时,会挂起(中断),等下一帧,所有的脚本Update运行完后,会继续执行此函数。所以上图的意思是回去检测所有因yield null挂起的协程并恢复。