<p>作者:<a href="http://weibo.com/wangxuanyihaha">王选易</a>,出处:<a href="http://www.cnblogs.com/neverdie/">http://www.cnblogs.com/neverdie/</a> <strong>欢迎转载</strong>,也请保留这段声明。如果你喜欢这篇文章,请点<strong>推荐</strong>。谢谢!</p> <blockquote> <p><a href="http://static.oschina.net/uploads/img/201405/30151827_wwKU.jpg"><img title="QQ图片20140529123319" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="QQ图片20140529123319" src="http://static.oschina.net/uploads/img/201405/30151827_snhv.jpg" width="254" height="120" /></a></p> </blockquote> <h3>引子</h3> <p>上一次我们讲了<a href="http://www.cnblogs.com/neverdie/p/3758829.html">GameObject,Compoent,Time,Input,Physics</a>,其中Time,Input,Physics都是Unity中的全局变量。GameObject是游戏中的基本物件。GameObject是由Component组合而成的,GameObject本身必须有Transform的Component,这也加深了我们对GameObject的理解,即GameObject是游戏场景中真实存在,而且有位置的一个物件。</p> <p>但是我们怎么操纵这个GameObject呢?这就需要引入脚本组件了,也就是今天讲的MonoBehaviour</p> <h3>MonoBehaviour的生命周期</h3> <p>MonoBehaviour是Unity中所有脚本的基类,如果你使用JS的话,脚本会自动继承MonoBehaviour。如果使用C#的话,你需要显式继承MonoBehaviour。</p> <p>在我们使用MonoBehaviour的时候,尤其需要注意的是它有哪些可重写函数,这些可重写函数会在游戏中发生某些事件的时候被调用。我们在Unity中最常用到的几个可重写函数是这几个:</p> <ul> <li>Awake:当一个脚本实例被载入时Awake被调用。我们大多在这个类中完成成员变量的初始化 </li> <li>Start:仅在Update函数第一次被调用前调用。因为它是在Awake之后被调用的,我们可以把一些需要依赖Awake的变量放在Start里面初始化。 同时我们还大多在这个类中执行StartCoroutine进行一些协程的触发。要注意在用C#写脚本时,必须使用StartCoroutine开始一个协程,但是如果使用的是JavaScript,则不需要这么做。 </li> <li>Update:当MonoBehaviour启用时,其Update在每一帧被调用。 </li> <li>FixedUpdate:当MonoBehaviour启用时,其 <a href="http://game.ceeger.com/Script/MonoBehaviour/MonoBehaviour.FixedUpdate.html">FixedUpdate </a>在每一<strong>固定帧</strong>被调用。 </li> <li>OnEnable:当对象变为可用或激活状态时此函数被调用。 </li> <li>OnDisable:当对象变为不可用或非激活状态时此函数被调用。 </li> <li>OnDestroy:当MonoBehaviour将被销毁时,这个函数被调用。 </li> </ul> <p>下面用一张图来更形象地说明一下这几个类的在MonoBehaviour的生命周期中是如何被调用的:</p> <p><a href="http://static.oschina.net/uploads/img/201405/30151828_IGCq.png"><img title="lifecycle" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="lifecycle" src="http://static.oschina.net/uploads/img/201405/30151830_8F0h.png" width="804" height="1088" /></a></p> <p>在上面这个图里,比较难以理解的就是Coroutine究竟是怎么回事?别着急,之后我们会单独写一篇博客来讲这件事。</p> <p> </p> <h3>MonoBehaviour的那些坑</h3> <ul> <li>私有(private)和保护(protected)变量只能在专家模式中显示.属性不被序列化或显示在检视面板. </li> <li>不要使用命名空间(namespace) </li> <li>记得使用 <strong>缓存组件查找, </strong>即在MonoBehaviour的长远方法中经常被访问的组件最好在把它当作一个私有成员变量存储起来。 </li> <li>在游戏里经常出现需要检测敌人和我方距离的问题,这时如果要寻找所有的敌人,显然要消耗的运算量太大了,所以最好的办法是将攻击范围使用Collider表示,然后将Collider的isTrigger设置为True。最后使用OnTriggerEnter来做攻击范围内的距离检测,这样会极大提升程序性能。 </li> </ul> <h3>总结</h3> <p>在MonoBehaviour中最难理解的是Coroutine是如何实现的,但是如果在一篇博客里面写Coroutine的话,未免显得太长,我会在下一篇博客中写有关Coroutine的内容。</p>