脚本执行顺序

前言

搭建一个示例来验证Unity脚本的执行顺序,大概测试以下部分:

  • 物理方面(Physics)
  • 渲染(Scene rendering)
  • 输入事件(InputEvent)

流程图

Unity文档:https://docs.unity3d.com/Manual/ExecutionOrder.html

原图地址:https://docs.unity3d.com/uploads/Main/monobehaviour_flowchart.svg

测试场景

搭建场景

示例下载:https://github.com/zhaoqingqing/blog_samplecode/raw/master/unity-framework/monobehaviour_lifecycle/monobehaviour_lifecycle.unitypackage

根据上图中的脚本生命周期,我编写三个脚本来测试部分阶段的生命周期:

  • Logs.cs 输出日志(可选)
  • TestInputEvent.cs(Input输入事件)
  • TestPhysicOrder.cs(物理事件执行顺序)
  • TestSceneRender.cs(Render顺序)

创建一个空的场景,创建三个Gameobject,每个gameobject上分别绑上要测试的脚本。每次测试不同的功能,分别激活不同的gameobject

打印调用堆栈脚本

可以打印调用方法的堆栈,包括方法名,文件名

github:https://github.com/zhaoqingqing/blog_samplecode/blob/master/unity-framework/monobehaviour_lifecycle/Logs.cs

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的各个脚本函数,大致内容如下:

github:https://github.com/zhaoqingqing/blog_samplecode/blob/master/unity-framework/monobehaviour_lifecycle/TestPhysicOrder.cs

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测试

测试脚本

github:https://github.com/zhaoqingqing/blog_samplecode/blob/master/unity-framework/monobehaviour_lifecycle/TestSceneRender.cs

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(生命周期/脚本执行顺序)的更多相关文章

  1. Unity脚本生命周期与执行顺序

    文章目录 脚本生命周期 MonoBehavior生命周期图 脚本执行顺序 自定义执行顺序 在Unity中,脚本可以理解为附加在游戏对象上的用于定义游戏对象行为的指令代码.必须绑定在游戏对象上才能开始它 ...

  2. 附实例!图解React的生命周期及执行顺序

    本文由云+社区发表 作者:前端林子 1.七个可选的生命周期 可以结合下图来看: (1) componentWillMount() 仅在render()方法前被调用一次,如果在该方法中调用了setSta ...

  3. Spring的Bean的生命周期方法执行顺序测试

    通过一个简单的Maven工程来演示Spring的Bean生命周期函数的执行顺序. 下面是工程的目录结构: 直接贴代码: pom.xml文件内容: <?xml version="1.0& ...

  4. Unity3D脚本的生命周期(执行顺序)

    Unity脚本中有许多固定的函数 例如Start();Update(); 而这些函数都有固定的执行顺序 搞清楚这些函数的执行顺序 对于我们理清代码的逻辑就显得尤为重要 举个简单的例子 //脚本A pu ...

  5. vue中的父组件及子组件生命周期的执行顺序

    一.没有任何任何显示与隐藏限制条件的情况下: 1.运行的顺序依次是: 父组件created→父组件beforeMounted→子组件created→子组件beforeMounted→子组件mounte ...

  6. 简单记录一下vue生命周期及 父组件和子组件生命周期钩子执行顺序

    首先,vue生命周期可以用下图来简单理解 当然这也是官方文档的图片,详细的vue周期详解请参考这里 然而当同时存在父子组件的时候生命周期钩子是如何执行的呢? 请看下文: 加载渲染过程父beforeCr ...

  7. react教程 — 组件的生命周期 和 执行顺序

    一.组件执行的生命周期:                  参考  https://www.cnblogs.com/soyxiaobi/p/9559117.html  或  https://www.c ...

  8. Vue 的父组件和子组件生命周期钩子执行顺序是什么

    加载渲染过程父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount-&g ...

  9. Unity3D_02_基类MonoBehaviour/自带函数以及脚本执行的生命周期

    导引: 其中Time,Input,Physics都是Unity中的全局变量.GameObject是游戏中的基本物件.GameObject是由Component组合而成的,GameObject本身必须有 ...

随机推荐

  1. eclipse打开文件所在目录

    设置 添加扩展工具,添加步骤如下: Run-->External Tools-->External Tools Configurations... new 一个 programlocati ...

  2. 无限循环轮播图之结构布局(原生JS)

    html部分 <div class="box" id="box"> <ul> <li><img src="i ...

  3. 1、.NET平台概述

        本学习主要参考Andrew Troelsen的C#与.NET4高级程序设计,这小节主要述说以下几个东西:     宏观上讨论一下.net相关的主题:程序集.CIL(Common Interme ...

  4. Vertica增加一个数据存储的目录

    Vertica增加一个数据存储的目录 操作语法为: ADD_LOCATION ( 'path' , [ 'node' , 'usage', 'location_label' ] ) 各节点添加目录,并 ...

  5. 你真的会玩SQL吗?你所不知道的 数据聚合

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  6. MyCat源码分析系列之——前后端验证

    更多MyCat源码分析,请戳MyCat源码分析系列 MyCat前端验证 MyCat的前端验证指的是应用连接MyCat时进行的用户验证过程,如使用MySQL客户端时,$ mysql -uroot -pr ...

  7. 学习javascript数据结构(一)——栈和队列

    前言 只要你不计较得失,人生还有什么不能想法子克服的. 原文地址:学习javascript数据结构(一)--栈和队列 博主博客地址:Damonare的个人博客 几乎所有的编程语言都原生支持数组类型,因 ...

  8. .Net语言 APP开发平台——Smobiler学习日志:如何实现快速跳转网页

    Smobiler是一个在VS环境中使用.Net语言来开发APP的开发平台,也许比Xamarin更方便 样式一 一.跳转网页代码(Button的Click事件) Private Sub Button1_ ...

  9. AutoResetEvent ManualResetEvent WaitOne使用注意事项

    公司还用这些老家伙没办法,用了几次这俩.每次用都要重新翻一下A片. 好好的A片楞是翻译成了禅经.把这东西弄成个玄学.微软也是吃枣药丸.参考了@风中灵药的blog.写的牛逼. 还有一些公司用到的风中灵药 ...

  10. Jedis的使用

    Redis是常用的key-value存储服务器,Java使用Redis有很多方法,其中官方推荐的是Jedis. 使用Jedis,首先是下载jedis-x.x.x.jar文件并导入工程,然后运行Redi ...