专栏首页韩东吉的Unity杂货铺零基础入门 9: Unity脚本的生命周期

零基础入门 9: Unity脚本的生命周期

因为接下来的几篇分享,可能会开始编写脚本,所以索性用这篇来介绍下Unity脚本的常用生命周期函数。

一说到生命周期函数,很多小伙伴的表情就是这样的

Unity脚本还有生命周期函数?吃惊!(Σ(⊙▽⊙"a )

这篇主要分享下有关生命周期的内容。


实际上Unity脚本的生命周期函数有很多,但是常用的却只有一部分。

先来贴一张qitian67博文曾发出来的一张图。大家来感受下。

上面一张图,描述了Unity在3.4版本时的脚本生命周期函数流程图的部分内容。

简单的文字描述下运行模式下的流程。

Awake(只调用一次)

OnEnable(每次激活都会被调用)

Start(只调用一次)

FixedUpdate(固定时间调用,时间可调)

Update(每帧调用,不同设备帧率不同,调用次数不同)

LateUpdate(延迟调用)

OnGUI(实际项目运行使用很少,适用于编写工具脚本)

OnDisable(每次隐藏都会被调用)

OnDestroy(被销毁时调用一次)

上面是Unity脚本常用的运行时生命周期函数时序图,其中

Awake是唤醒函数,代表脚本运行时第一个调用的函数入口。

FixedUpdate按照固定帧刷新调用。(固定值可调)

Update(每帧调用)

LateUpdate(延迟帧调用)

OnEnable和OnDisable会在脚本反复的激活和禁用时被调用,非一次性调用生命周期函数。

(请注意:上面的流程图,是Unity3.4版本的生命周期函数时序)

下面我们创建一个空的脚本,来重新验证下,现在的Unity生命周期函数的调用顺序。

如下图,我们创建一个脚本,名为TestSL(TestScriptLife)

打开脚本,进行编辑,增加生命周期函数。

上图内的自带生命周期函数是创建脚本的模板,至于如何创建一个新的脚本就自带模板内容,请翻看之前分享的内容重温一下。

然后我们在Update函数上下分别增加FixedUpdate和LateUpdate函数。

然后我们在每一个生命周期函数里加入Debug日志输出来查看调用顺序。

Debug.LogError的意思是输出一条红色的错误日志。“”里面的内容就是日志的内容。

然后切回到项目里,创建一个空的GameObject。将TestSL挪到GameObject上。

此时GameObject上就有个这个TestSL脚本,然后我们运行游戏,查看日志的输出顺序即可知道生命周期函数的调用顺序。

如上图,我们发现项目运行后,短短几秒就打出了578条日志,非常不方便我们观看日志。

所以我们对脚本进行一些小修改,让FixedUpdate,Update,LateUpdate这种帧调用的函数只输出一次日志,这样可以方便我们直接观看。

如下图,我们给三个Update函数定义三个计数器。默认为0。

如下图,我们在FixedUpdate函数里加入几行代码

第一行m_f+=1;

我们让m_f += 1,m_f+= 1这句代码可以理解成m_f = m_f+1,当前m_f为0,当函数调用一次后,m_f+=1,m_f = 0+1;这样m_f就会变成1。

第二行代码

if(m_f > 1)

return;

意思就是如果m_f这个值大于1了,那么就直接退出这个函数。

但是这样的写法,每次进入FixedUpdate函数依然会打出Log,那怎么办?

如下图,我们把Debug这句话放到逻辑代码下面就行了,并且给Update和LateUpdate都加上这样的逻辑。

然后再次回到Unity,重新运行。

上图中,我们运行后发现,频繁的日志不见了,目的达到了,但是为什么只有6条日志呢?明明我们脚本里输出了8句。

原因是我们把脚本挂在了GameObject上,但是OnDisable是在对象禁用(或者隐藏)时调用,OnDestroy是在对象销毁的时候调用。

我们重新运行一次看看。这次我们加入对GameObject对象的隐藏和删除。

(为了不被我蓝色的运行模式颜色而影响大家看日志,所以我暂时还原回去了运行的背景颜色。(゚ー゚))

从上图我们可以看出,当我们对GameObject隐藏后,OnDisable就输出了,删除对象后,OnDestroy就输出了。

我把全的日志图放上来。

从上图,我们就可以彻底看出来整个脚本的生命周期函数调用顺序。

既然前面说到了FixedUpdate是按照一个可调的固定时间调用的,那么这个时间怎么改呢?按照下图操作,点开Time

默认值如下图,0.02

如下图操作,我们将时间修改为1,并且在代码内,把限制FixedUpdate日志输出的函数注释,然后回到Unity运行游戏,可以看出,FixedUpdate日志以固定1秒输出一条日志。

说一个题外篇,我们把TestSL脚本挂载到了GameObject对象上,截图如下。

脚本前面有一个√对勾,可以供使用者启用或者不启用脚本。

但是有的时候我们发现,有的脚本前面没有这个√对勾,是怎么回事呢?

答案和生命周期函数也有关。

如下图,我们点击Inspector面板,可以通过对勾来选择是否启用脚本。

什么情况下,这个对勾会消失呢?

答案很简单,我们回到脚本,把所有生命周期函数进行注释。然后切回到Unity

如上图,当脚本内没有生命周期函数的时候,脚本前的对勾就消失了。如果把生命周期函数的注释去掉,那么对勾就会出现。

经过缜密的实际测试,除了Awake和OnDestroy以外,脚本有未注释的生命周期函数,Inspector都会出现对勾√,下图为只有Awake和OnDestroy未注释状态,Inspector面板依然没有对勾出现。

好了,今天的Unity脚本生命周期函数就分享到这了。有疑问的点大家可以给我留言。

本文分享自微信公众号 - 韩东吉的Unity杂货铺(DeveloperJimin),作者:Jimin

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-01-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 零基础入门 37:加强版日志窗口

    又是俩星期不见,大家好,刚刚忙完,所以现在深夜更新,今天的主题描述我用语音和大家来介绍。

    韩东吉
  • 零基础入门 36:代码控制预设

    上一篇分享给大家带来了如何通过菜单栏呼出一个自定义的窗口,不知道大家消化的如何了呢?

    韩东吉
  • 零基础入门 1: 环境布置

    【Unity零基础入门】今天开始不定期更新,可能你之前有了解过Unity,或者对Unity一点也不了解, 又或者你现在正在从事Unity的相关工作,不管是哪种情...

    韩东吉
  • 初创公司该如何做好持续集成和部署

    作者简介 裴双才,Geekwolf,现MAKA运维负责人,博客: http://www.simlinux.com 《FastDFS分布式存储实战》作者,《An...

    DevOps时代
  • python | 学习总结 urllib.request

    Number of Rows of Data =208 Number of Columns of Data =61

    努力在北京混出人样
  • 剑指Offer-字符流中第一个不重复的字符

    package String; import java.util.LinkedHashMap; import java.util.Map; /** * 字...

    武培轩
  • OO:UML类图、六大关系

    WEBJ2EE
  • 使用ELK收集网络设备日志的案例

    基于上述原因,在当前的网络环境中搭建一台用于日志集中管理的Rsyslog日志服务器就显得十分有必要了。

    没有故事的陈师傅
  • MySQL 通用查询日志(General Query Log)

        同大多数关系型数据库一样,日志文件是MySQL数据库的重要组成部分。MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志,慢查询日...

    Leshami
  • 【干货合辑】毕业季,如何敲开「IT世界」的大门

    现在 IT 新技术日新月异,IT 行业的工作也变得赤手可热。刚毕业的大学生也蜂拥而至,但是在校的学习经验并没有一定的专业领域的实操经验,而被企业拒之门外。那么,...

    云加社区

扫码关注云+社区

领取腾讯云代金券