古人云:笔耕不缀,必有收获。
最近小编在忙着找工作,在这了给自己大个广告啊(敲黑板)
两年移动游戏unity前端开发程序员一枚,地点北京西三旗附近(最近接到一些面试邀请,但是都很远,实在是不想把时间都浪费在路上,又时间还不如写文章骗赞赏呢~~)。本人吃苦耐劳,熟悉untiy前端各功能模块的设计与开发,熟悉Android多个渠道的sdk接入。期望薪资~~这个感觉不适合在这里写。好了,广告结束,下面正文
前面两篇文,咱们介绍了一下unity的主要界面窗口以及工程目录。
那么,作为一名前端程序,最基本的工作可能就是生命周期,下面一张图是从unity的官方文档中截取的,如果看不清可以跳转到官方地址查看哦
unity官方文档地址(顺便提一下,学习unity最快的途径就是查看官方文档,学习unity最稳的途径就是查看官方文档,233官方文档给我宣传费么~~)
那么什么是生命周期呢?我们要知道,游戏前端编程是一个面向对象思想贯穿的过程,游戏中的每一个物体,每一个脚本都是一个对象,对象是什么?没错,英文名Object,直翻就是“东西”,每一个东西都有生命周期,从产生到销毁,中间经历一些特殊事件、一些循环往复的事情。这些就是我们谈到生命周期的时候要了解的事情。
什么样的脚本有生命周期?继承了MonoBehaviour类的脚本,我们将它称为一个控件(Component)MonoBehaviour类是unity提供的一个基类,继承了这个基类的类就具有了生命周期。
生命周期什么是后开始?当这个脚本被挂在到游戏场景中active的物体上的时候,生命周期开始,直到脚本被销毁。
继承了Monobehavior的类会同时继承上图中所有的方法,每一个方法对应着生命周期的一个环节,在这个方法中编写的逻辑会在相应环节被执行。
我们先来简单介绍一下怎么看这个图:这个生命周期图从上到下是一个完整的生命周期,左侧是对周期中每个事件的解释,右边将多个周期合并归类。
比如最上面的Reset,他的右侧写了个Editor,那么我们知道他是在编辑模式下使用的方法,而不是运行时的。往往做unity的插件的时候会用到,实际游戏运行时是不需要的,我们暂且不去理会他。
那么接下来的三个,Awake,OnEnable,Start,他们三个右侧写着Initialization(初始化),他们三个是用来初始化脚本的,比如做一些变量的赋值,对对象的属性做某些设定。那么他们的区别在于,Awake在整个生命周期中只会执行一次,OnEnable对应着下面的OnDisable,实现了对象active属性的监听(如下图,我们随意创建一个cube,在Inspector中查看他的属性,在右上角有一个选择框,当这个框从非选择状态变为选中状态时,会执行一次OnEnable,返过来则会执行OnDisable),我们暂时不去讲解如何在代码中控制这个开关,在这个时候,我们就手动去点击测设吧。Start方法在一个生命周期中也只会执行一次,但是这一次一定是在OnEnable之后(幸好文档在左侧注释了一下这个特性,不然我还以为每次执行完OnEnable之后都会执行Start方法呢)
到这里我们来做一个简单的测试:
首先我们在project窗口右键create一个c# Script,我们不妨给他起名字叫做FirstScript
然后我们在Hierarchy右键创建一个3D Object--Cube,我们将我们的脚本拖动到这个物体上(这个过程会将我们的脚本挂在到Cube上),这时候我们点击我们的Cube物体,在Inspector窗口可以看到他的属性,如下图,我们看到这里已经挂载了我们拖动上去的脚本。
下面我们双击我们的脚本,开始编辑她。
我们来测试我们刚刚提到的Awake、OnEnable、Start、OnDisable
打开的脚本我们观察一下,他继承了MonoBehavior类,并且已经写入了两个方法Start和Update,我们暂且把Update方法放到一边,然后加入我们要测试的方法,就像下图
我们要如何知道他执行了哪一个方法呢?没错,打log。Unity打想Console控制台打log有下面几种常用的方法
Debug.Log("");
Debug.LogWarning("");
Debug.LogError("");
分别对应了log的三个等级
我们写好log输出之后类似于下面这样子
接下来,在最后运行前,我们做一个小动作。我们把Cube上的刚提到的选择框取消选择,这样他的初始状态就是Disable的。
然后,我们点击正中间上方的运行按钮来运行我们的“游戏”
我们会发现,我们的控制台没有任何输出!没有错,就是这样,在Disable状态下,不会执行这个物体上所有脚本的任何生命周期相关的脚本!
接下来,我们不要停止运行,点击选择框,使它成为Enable状态,我们发现控制台有输出了,如下图,依次输出了Awake方法,OnEnable方法,Start方法。现在我们证实了第一次激活脚本的时候,这三个方法的执行顺序
接下来,我们通过点击取消掉选择。如我们所料,控制台多了一个OnDisable的输出
最后,我们再次点击,勾上选择框,我们发现控制台只增加了一个OnEnable,而另外两个方法Awake和Start并没有再次执行,这就证实了Awake和Start在一个生命周期中只执行一次的结论。
剩下的生命周期的方法小编就不去给大家一一验证了,我们说几个常用的:
1、FixedUpdate\Update\LateUpdate
这三个事件在生命周期中就像人类呼吸一样周而复始,每一帧都会调用。但是他们三个又有各自的特点:
FixedUpdate是固定时长的,这个时长默认是0.02s,我们可以在Edit->ProjectSetting->time中来设置他。我们常在这里处理刚体的物理运动,由于刚体的物理 运动往往是与时间相关,所以在固定市场的FixedUpdate中处理是最好的选择。
Update每帧执行的一个方法,但是这个会受到设备性能的影响,比如在30fps和60fps下,同一个Update方法的步长是不相等的,在这里处理一些渲染的操作。
LateUpdate总是在所有Update方法之后执行,在Unity圣典中他是这样描述的:
在圣典里LateUpdate被解释成一句话:LateUpdate是在所有Update函数调用后被调用。这可用于调整脚本执行顺序。例如:当物体在Update里移动时,跟随物体的相机可以在LateUpdate里实现。
那么,什么叫做所有Update函数调用之后呢~~他的意思是当前所有在场景中,并且正常执行生命周期的控件,他们的所有Update方法执行之后才会调用LateUpdate。这样做的好处呢?当有两个以上的脚本在Update里处理了一个运动,这时这个运动可能会有一些“不正常”,比如我们现在有一个相机要跟随这个物体,如果我们把相机的运动写到某个Update里,相机很容易产生抖动现象,而写到LateUpdate里,等到这一帧物体的动作渲染结束了,我们再去执行相机的跟随,就可以避免相机的抖动。
2、OnDisable、OnDestroy
前面我们跟OnEnable一起提到了OnDisable,我们知道每次物体的active属性从true变为false的时候会执行OnDisable
但是还有一种情况,当物体被从场景中删除,也就是我们常说的销毁的时候,也会执行OnDisable,这时候的流程是先执行OnDisable,再执行OnDestroy。
其实常用的也就上面这几个方法了,其他的,可以自己根据官方文档学习一下,用来秀一下操作还是棒棒哒。
好啦,夜深啦,一写就是一个多小时。