MonoBehaviour Lifecycle(生命周期/脚本执行顺序)

本文为作者原创,转载请注明出处:https://www.cnblogs.com/zhaoqingqing/p/5990370.html



脚本执行顺序#

前言#

搭建一个示例来验证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

Copy
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

Copy
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

Copy
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上

作者:赵青青   一名在【网易游戏】做游戏开发的程序员,擅长Unity3D,游戏开发,.NET等领域。
本文版权归作者和博客园共有,欢迎转载,转载之后请务必在文章明显位置标出原文链接和作者,谢谢。
如果本文对您有帮助,请点击【推荐】您的赞赏将鼓励我继续创作!想跟我一起进步么?那就【关注】我吧。
posted @   赵青青  阅读(4062)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
阅读排行:
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 易语言 —— 开山篇
· Trae初体验
历史上的今天:
2015-10-25 Remove Rar Password OnLine
2015-10-25 Windows系统小知识
2015-10-25 C# 事件编程在游戏开发的应用
2014-10-25 Cg关键字(keywords)
2013-10-25 NGUI学习笔记汇总
CONTENTS
点击右上角即可分享
微信分享提示