MonoBehaviour Lifecycle(生命周期/脚本执行顺序)
脚本执行顺序
前言
搭建一个示例来验证Unity脚本的执行顺序,大概测试以下部分:
- 物理方面(Physics)
- 渲染(Scene rendering)
- 输入事件(InputEvent)
流程图
Unity文档:https://docs.unity3d.com/Manual/ExecutionOrder.html
原图地址:https://docs.unity3d.com/uploads/Main/monobehaviour_flowchart.svg

测试场景
搭建场景
根据上图中的脚本生命周期,我编写三个脚本来测试部分阶段的生命周期:
- Logs.cs 输出日志(可选)
- TestInputEvent.cs(Input输入事件)
- TestPhysicOrder.cs(物理事件执行顺序)
- TestSceneRender.cs(Render顺序)
创建一个空的场景,创建三个Gameobject,每个gameobject上分别绑上要测试的脚本。每次测试不同的功能,分别激活不同的gameobject

打印调用堆栈脚本
可以打印调用方法的堆栈,包括方法名,文件名
using System;
using System.Diagnostics;
public class Logs {
/// <summary>
/// 打印调用者的方法名
/// </summary>
public static void DoLog()
{
StackTrace st = new StackTrace(true);
//获取当前调用的方法名
StackFrame stackFrame = st.GetFrame(1);
//var callInfo = string.Format("{0}:{1}.{2}",stackFrame.GetFileName(),stackFrame.GetFileLineNumber(),stackFrame.GetMethod().Name);
var callInfo = stackFrame.GetMethod().Name.ToString();
DoLog(callInfo);
}
public static void DoLog(string szMsg, params object[] args)
{
string log = string.Format("[{0}]{1}", DateTime.Now.ToString("HH:mm:ss.ffff"), string.Format(szMsg, args));
UnityEngine.Debug.Log(log);
}
}
物理测试
测试脚本
测试脚本中写了Unity的各个脚本函数,大致内容如下:
using System;
using UnityEngine;
using System.Collections;
public class TestPhysicOrder : MonoBehaviour
{
// Reset to default values
public void Reset()
{
Logs.DoLog();
}
// Awake is called when the script instance is being loaded
public void Awake()
{
StartCoroutine(YieldOneFrame());
StartCoroutine(YieldEndOfFrame());
StartCoroutine(YieldWaitForFixedUpdate());
Logs.DoLog();
}
// This function is called when the object becomes enabled and active
public void OnEnable()
{
Logs.DoLog();
}
// Use this for initialization
void Start()
{
Logs.DoLog();
}
// This function is called every fixed framerate frame, if the MonoBehaviour is enabled
public void FixedUpdate()
{
Logs.DoLog();
}
// Update is called once per frame
void Update()
{
Logs.DoLog();
}
IEnumerator YieldWaitForFixedUpdate()
{
yield return new WaitForFixedUpdate();
Logs.DoLog("WaitForFixedUpdate");
}
IEnumerator YieldOneFrame()
{
yield return 1;
Logs.DoLog("YieldOneFrame");
}
IEnumerator YieldEndOfFrame()
{
yield return new WaitForEndOfFrame();
Logs.DoLog("YieldEndOfFrame");
}
// LateUpdate is called every frame, if the Behaviour is enabled
public void LateUpdate()
{
Logs.DoLog();
}
// This function is called when the behaviour becomes disabled or inactive
public void OnDisable()
{
Logs.DoLog();
}
// This function is called when the MonoBehaviour will be destroyed
public void OnDestroy()
{
Logs.DoLog();
}
// Sent to all game objects when the player gets or looses focus
public void OnApplicationFocus(bool focus)
{
Logs.DoLog();
}
// Sent to all game objects when the player pauses
public void OnApplicationPause(bool pause)
{
Logs.DoLog();
}
// Sent to all game objects before the application is quit
public void OnApplicationQuit()
{
Logs.DoLog();
}
}
测试结果
开始部分截图

结束部分截图

Render测试
测试脚本
using System;
using UnityEngine;
public class TestSceneRender : MonoBehaviour
{
// OnPreCull is called before a camera culls the scene
public void OnPreCull()
{
Logs.DoLog();
}
// OnPreRender is called before a camera starts rendering the scene
public void OnPreRender()
{
Logs.DoLog();
}
// Callback that is sent if an associated RectTransform has it's dimensions changed
public void OnRectTransformDimensionsChange()
{
Logs.DoLog();
}
// Callback that is sent if an associated RectTransform is removed
public void OnRectTransformRemoved()
{
Logs.DoLog();
}
// OnRenderImage is called after all rendering is complete to render image
public void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Logs.DoLog();
}
// OnRenderObject is called after camera has rendered the scene
public void OnRenderObject()
{
Logs.DoLog();
}
// OnWillRenderObject is called once for each camera if the object is visible
public void OnWillRenderObject()
{
Logs.DoLog();
}
// Implement this OnDrawGizmosSelected if you want to draw gizmos only if the object is selected
public void OnDrawGizmos()
{
Logs.DoLog();
}
// OnGUI is called for rendering and handling GUI events
public void OnGUI()
{
Logs.DoLog();
}
}
测试结果
当把测试脚挂在Cube或者Camera上,会执行的函数是不相同的。
绑在Camera上

绑在Cube上

MonoBehaviour Lifecycle(生命周期/脚本执行顺序)的更多相关文章
- Unity脚本生命周期与执行顺序
文章目录 脚本生命周期 MonoBehavior生命周期图 脚本执行顺序 自定义执行顺序 在Unity中,脚本可以理解为附加在游戏对象上的用于定义游戏对象行为的指令代码.必须绑定在游戏对象上才能开始它 ...
- 附实例!图解React的生命周期及执行顺序
本文由云+社区发表 作者:前端林子 1.七个可选的生命周期 可以结合下图来看: (1) componentWillMount() 仅在render()方法前被调用一次,如果在该方法中调用了setSta ...
- Spring的Bean的生命周期方法执行顺序测试
通过一个简单的Maven工程来演示Spring的Bean生命周期函数的执行顺序. 下面是工程的目录结构: 直接贴代码: pom.xml文件内容: <?xml version="1.0& ...
- Unity3D脚本的生命周期(执行顺序)
Unity脚本中有许多固定的函数 例如Start();Update(); 而这些函数都有固定的执行顺序 搞清楚这些函数的执行顺序 对于我们理清代码的逻辑就显得尤为重要 举个简单的例子 //脚本A pu ...
- vue中的父组件及子组件生命周期的执行顺序
一.没有任何任何显示与隐藏限制条件的情况下: 1.运行的顺序依次是: 父组件created→父组件beforeMounted→子组件created→子组件beforeMounted→子组件mounte ...
- 简单记录一下vue生命周期及 父组件和子组件生命周期钩子执行顺序
首先,vue生命周期可以用下图来简单理解 当然这也是官方文档的图片,详细的vue周期详解请参考这里 然而当同时存在父子组件的时候生命周期钩子是如何执行的呢? 请看下文: 加载渲染过程父beforeCr ...
- react教程 — 组件的生命周期 和 执行顺序
一.组件执行的生命周期: 参考 https://www.cnblogs.com/soyxiaobi/p/9559117.html 或 https://www.c ...
- Vue 的父组件和子组件生命周期钩子执行顺序是什么
加载渲染过程父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount-&g ...
- Unity3D_02_基类MonoBehaviour/自带函数以及脚本执行的生命周期
导引: 其中Time,Input,Physics都是Unity中的全局变量.GameObject是游戏中的基本物件.GameObject是由Component组合而成的,GameObject本身必须有 ...
随机推荐
- 简单使用Git和Github来管理自己的代码和读书笔记
原文链接:http://my.oschina.net/bxxfighting/blog/378196 先注册github.com的账号官方网站: https://github.com/ 注册界面, ...
- Android消息传递之组件间传递消息
前言: 上篇学习总结了Android通过Handler消息机制实现了工作线程与UI线程之间的通信,今天来学习一下如何实现组件之间的通信.本文依然是为学习EventBus做铺垫,有对比才能进步,今天主要 ...
- .NET Core采用的全新配置系统[4]: “Options模式”下各种类型的Options对象是如何绑定的?
旨在生成Options对象的配置绑定实现在IConfiguration接口的扩展方法Bind上.配置绑定的目标类型可以是一个简单的基元类型,也可以是一个自定义数据类型,还可以是一个数组.集合或者字典类 ...
- 添加 Pool Member - 每天5分钟玩转 OpenStack(123)
我们已经有了 Load Balance Pool "web servers"和 VIP,接下来需要往 Pool 里添加 member 并学习如何使用 cloud image. 先准 ...
- java中的文件读取和文件写出:如何从一个文件中获取内容以及如何向一个文件中写入内容
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...
- SQL Tuning 基础概述03 - 使用sql_trace和10046事件跟踪执行计划
1.使用sql_trace跟踪执行计划 1.1 当前session跟踪: alter session set sql_trace = true; //开始sql_trace alter session ...
- 学习Spring——两个你熟悉的不能再熟悉的场景使用
最近公众号受邀获取了留言和赠送模板的权限,小开心(欢迎去公众号JackieZheng围观). 我们大致的了解了Spring这个框架对于依赖注入的使用和诠释可谓是淋漓尽致.因为有了Spring的这个IO ...
- jQuery2.x源码解析(设计篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 这一篇笔者主要以设计的角度探索jQuery的源代 ...
- 微信支付:H5吊起支付API,不显示“确认支付、输入密码”界面
使用公众号进行支付,官方开发帮助文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1 其业务流程如下: 按照业务流程进行开发 ...
- 总结:如何使用redis缓存加索引处理数据库百万级并发
前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1000万条数据,可以参考我之前的文章插入数据, ...