Unity学习笔记(2)- MonoBehaviour类的生命周期及脚本报错收集

原创 2017年05月14日 15:23:18

       在Unity中,脚本的职责就是做GameObject的逻辑驱动,所有需要挂载到GameObject上面的脚本,都需要继承自MonoBehaviour,MonoBehaviour是Unity中所有脚本驱动的基类(当你使用C#作为脚本语言时)。MonoBehaviour有一些事件函数会在特定的时间被调用,Unity的MonoBehaviour脚本的生命周期示意图如下:


        需要说明的是,当脚本被绑定在GameObject上时,可以通过点选前方的复选框来决定这些事件函数是否会被激活调用。

                                  

        需要特定说明的几个函数调用时间的区分:

        Awake和Start:Awake在每次生命周期开始的时候被调用,之后会调用OnEnable函数,但是在Awake函数中如果调用this.enable=false;直接调用onDisable函数,另外你也可以在其他脚本或者逻辑直接调用this.enable=true;启动脚本,启动脚本后,会检测之前有没有调用过Start函数,如果没有,那么将调用Start函数,所以区别是Start会在Awake之后调用并且它的调用与否取决于this.enable。

       Update,FixedUpdate和LateUpdate:Update函数顾名思义,会在每一贞被调用,我们可以在这个函数中控制物体的位置从而实现物体的移动等等,但是需要注意的是,要尽量避免在Update中调用比较耗费效率的操作,因为它每帧都会被调用,同样的原则适用于FixedUpdate和LateUpdate。FixedUpdate与Update的不同在于,Update在每帧被调用,但是调用时间不确定,所以我们要实现一个物体匀速运动是,是无法通过Update准确实现的,但是我们可以在FixedUpdate中实现,因为它在确定的时间间隔中被调用,LateUpdate如图所示,它会在所有update被调用后调用,这个函数可以在我们编写ai时被使用,因为我们要当所有物体和怪物移动过后再判断物体的一些策略,比如开枪等,这个时候就可以在LateUpdate中编写,因为LateUpdate基本可以保证所有物体在本帧的移动等操作均已经完成。

关于所有事件函数api的参考可以参见:https://docs.unity3d.com/Manual/ExecutionOrder.html

      在我的框架中,为了收集脚本报错的功能,我在MonoBehaviour的基础上扩展了BaseMonoBehaviour,并让其他脚本继承自BaseMonoBehaviour,这个类后续还会扩展一些其他的全局功能。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
/*
 * 所有类的基类,逐步加入全局功能
 * 2017-5-1 收集报错信息
 */
public class BaseMonoBehaviour : MonoBehaviour {

	//输出句柄
	private System.IO.StreamWriter ExceptionStreamWriter;
	//报错文件名
	public string ExceptionFileName = "log.txt";

	void Awake () {
		ExceptionStreamWriter = new System.IO.StreamWriter (Application.persistentDataPath + "/" + ExceptionFileName);
		Debug.Log (Application.persistentDataPath + "/" + ExceptionFileName);
	}

	void Update () {
		
	}

	void OnEnable() {
		//注册报错
		Application.logMessageReceived += LogCallback;
	}

	void OnDisable() {
	}

	void OnDestroy() {
		ExceptionStreamWriter.Close ();
	}

	//收集报错
	void LogCallback(string logString, string stackTrace, LogType type) {
		if (type == LogType.Exception || type == LogType.Error) {
			ExceptionStreamWriter.WriteLine ("Logged at: " + System.DateTime.Now.ToString () + " - Log Des: " + logString + " - Trace:" + stackTrace + " - Type:"
				+ type.ToString());
		}
	}
}
       在OnEnable函数中注册收集报错函数,注意,这是Unity5新修改的注册方式,以前是通过调用函数注册,当LogCallback注册函数被调用的时候,就可以通过输出文件(或者将报错发到服务器)的方式收集报错,方便我们在游戏测试上线的过程中收集查询bug。
      最后,发现知乎上有一个关于是否要继承MonoBehaviour的讨论:https://www.zhihu.com/question/31163311,个人也有一些看法,我觉得这是个伪命题,因为当我们要把一个脚本绑定在GameObject上时,继承MonoBehaviour几乎是必须的,这样我们才能启动我们的脚本,因为Unity不是程序驱动,而是由场景驱动脚本,脚本也是资源的一部分,当我们的类是个纯逻辑类或者工具类全局类时,这时候就不必继承MonoBehaviour,当然就算继承自MonoBehaviour,它的事件函数也会因为没有绑定在GameObject上从而不会被调用,也就不存在性能问题,当然,为了代码整体的整洁和规范,可以规定只有需要绑定在GameObject上的脚本才继承自MonoBehaviour(本框架中采用baseMonoBehaviour)

      能力不足,水平有限,如有问题,欢迎讨论

       

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Unity学习笔记(1)-“Hello World”之Unity的调试和log

作为一个合格的程序员,持续保持学习的状态是十分必要,学习3d有一段时间了,期间接触过虚幻引擎,unity等3d引擎,个人的看法是虚幻引擎功能强大,但unity更适合开发手游,想来自己从2011年底开始...

CCOrbitCamera 使用

1.水平翻转: [CCOrbitCamera actionWithDuration:2 radius:1 deltaRadius:0 angleZ:0 deltaAngleZ:360 ...

cocos2d-x初探学习笔记(15)--CCOrbitCamera

小满(bill man)个人原创,欢迎转载,转载请注明地址,小满(bill man)的专栏地址http://blog.csdn.net/bill_man Cocos2d-x提供了一中根据球面坐标...

cocos2dx 利用CCOrbitCamera实现扑克牌翻牌效果

感谢点评与关注,欢迎转载与分享。 勤奋努力,持之以恒!

CCOrbitCamera-cocos2d翻转效果

cocos2d翻转效果" />   参数分别为旋转的时间,起始半径,半径差,起始z角,旋转z角差,起始x角,旋转x角差 使用举例: -(void) flipCard1 {    ...

cocos2d-x 3.6版本学习笔记-内存管理之Node对象

由于C++目前未提供完整的垃圾回收机制,cocos2d-x必须手动来管理内存。3.6版本里,cocos2d-x使用了一种类oc的内存管理机制,利用引用计算来控制对象的释放。 在cocos2d-x中,几...

Cocos2dx实现翻牌效果(CCScaleTo与CCOrbitCamera两种方式)

由于项目需要实现翻牌的效果,所以自己在完成的过程中将这篇文章写下来,想想还是觉得有点艰辛。 开始在网上找解决的办法找了很久,基本上就是一种解决方案,就是用CCOrbitCamera这个Action类...

cocos2d-x初探学习笔记(13)--内存回收机制

小满(bill man)个人原创,欢迎转载,转载请注明地址,小满(bill man)的专栏地址http://blog.csdn.net/bill_man 之前提到过cocos2d-x的内存回...

Unity3D 02-基类MonoBehaviour/自带函数以及脚本执行的生命周期

官方给出的脚本中事件函数的执行顺序如下图:Unity系统自带函数:using UnityEngine; using System.Collections; public class test :...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)