Unity生命周期,及相关内容

其实游戏引擎有一个基础简单理解,那就是不断的进行一个循环,在这个周期循环之中会每一帧的进行一些表现渲染上的处理,处理的结果就是我们看到的游戏画面,当然也会有各种各样的逻辑上的处理。
Unity是单线程的游戏引擎,为什么要做这个限制?因为游戏中逻辑更新和画面更新的时间点要求有确定性,必须按照帧序列严格保持同步,否则就会出现游戏中的对象不同步的现象。多线程也能保证这个效果,但如果引入多线程,会加大同步处理的难度与游戏的不稳定性。
unity有提供脚本周期,脚本的生命周期其实最最重要的就是这张图了,简单的可以把这个理解成,这是一个单线程的帧循环,每一次绘制都会重新走一遍生命周期。


image.png

Awake

游戏物体实例化后并处于激活状态时调用,即使脚本组件没有激活也会调用,而且总是在Start()函数之前调用

OnEnable

游戏物体与脚本组件激活时调用(会反复触发)

Start

游戏物体与脚本组件处于激活状态,在Update()运行前调用(只调用一次,当物体关闭激活状态,再打开时不会反复触发)

不同脚本间的,执行顺序:
Start是在场景所有物体的Awake与Enable全部执行完毕后进行调用。在unity中,多脚本的加载顺序是随机的。如果想直接进行对不同脚本Awake实例化的顺序控制的话,可以通过Script Execution Order来进行设置


image.png

FixedUpdate

FixedUFipdate,是每隔Time.fixedDeltaTime被调用一次。Time.fixedDeltaTime默认是0.02s,可以通过Edit->ProjectSettings->Time来设置。用来处理一些物理相关的内容,例如:给刚体加一个作用力时,你必须应用作用力在FixedUpdate里的固定帧,而不是Update中的帧(两者帧长不同)。
一个最简单的游戏循环大就是这样的,其中的frameTime 相当于,Time.deltaTime,它的时间其实是不固定的


image.png

那么如何实现FixedUFipdate 的固定增量时间呢,实现原理是 一个主循环中设置一个二级循环,以常量时间循环(其实在上面的生命周期中可以看出来)。


image.png

所以我们可以直接设置这个Time.fixedDeltaTime。

Update

update跟当前平台的帧数有关,Update是在每次渲染新的一帧的时候才会调用,也就是说,这个函数的更新频率和设备的性能有关以及被渲染的物体(可以认为是三角形的数量)。在性能好的机器上可能fps 30,差的可能小些。这会导致同一个游戏在不同的机器上效果不一致,有的快有的慢。因为Update的执行间隔不一样了。

LateUpdate

在调用所有Update函数后调用LateUpdate。这可用于调整脚本执行顺序。例如:当物体在Update里移动时,跟随物体的相机可以在LateUpdate里实现。

线程,协程 ##(游戏用到了大量的异步操作,这些是怎么实现的吗?)

协程是什么呢?总体来说,对与Unity,它是单线程的设计,它更倾向使用time slicing(时间分片)的协程(coroutine)去完成异步任务,融合到了刚刚提到的生命周期中。

要理解协程,先回顾下线程:线程是操作系统级别的概念,现代操作系统都实现并且支持线程,线程的调度对应用开发者是透明的,开发者无法预期某线程在何时被调度执行。基于此,一般那种随机出现的BUG,多与线程调度相关。

而协程Coroutine是编译器级的,本质还是一个线程时间分片去执行代码段。它通过**相关的代码使得代码段能够实现分段式的执行,显式调用yield函数后才被挂起,重新开始的地方是yield关键字指定的,一次一定会跑到一个yield对应的地方。因为协程本质上还是在主线程里执行的,需要内部有一个类似栈的数据结构,当该coroutine被挂起时要保存该coroutine的数据现场以便恢复执行。

在Unity3D中,协程是可自行停止运行 (yield),直到给定的 YieldInstruction 结束再继续运行的函数。 协程 (Coroutines) 的不同用途:

• yield; 在下一帧上调用所有 Update 函数后,协同程序将继续运行。

• yield WaitForSeconds(2); 在指定的时间延迟之后,为此帧调用所有 Update 函数之后继续运行

• yield WaitForFixedUpdate(); 在所有脚本上调用所有 FixedUpdate 后继续运行

• yield WWW 完成 WWW 下载后继续运行。

• yield StartCoroutine(MyFunc); 连接协同程序,并等待 MyFunc coroutine 首先结束。

也就是说,将代码段分散在不同的帧中,每次执行一段,下一帧再执行yield挂起的地方。

举个例子: 在OnStart()框架函数中调用startCoroutine(GetHttpData)执行以下代码端,其实是第一次发起网络请求,下一次执行时则走入yield之后的代码段继续执行,从而实现了一个时间分片的”异步”效果,而不是像线程那样在操作系统层面分CPU时间片去执行。

上面我们了解到了其实untiy是一个单线程的,但这些并不意味着无法在Unity中使用多线程,只是需要注意使用的场景。

试想一下,如果在帧序列的主循环单线程中处理大量耗时操作,势必会带来游戏画面的卡顿,帧率的下降。

因此,对于不是画面更新,也不是常规的逻辑更新(指包括AI、物理碰撞、角色控制这些),而是一些其他后台任务,则可以将这个独立出来开辟一个子线程。

所以,在不使用Unity SDK的前提下,确保做好主子线程的同步(采用C#中的delegate等机制),那么是可以合理使用子线程的。Unity限制使用多线程的原因主要是1.保证数据安全,2.降低编程难度。Unity在底层实现了线程池,引擎底层来实现一些可使用多线程处理的任务

概括起来,结合过往移动端的研发经验,我认为有以下几点可以在子线程中处理:
  大量耗时的数据计算
  网络请求
  复杂密集的I/O操作
  Unity3D的NativePlugin中可以新建子线程。通过NativePlugin可以接入移动端iOS与Android中的成熟库,可以是Objective C, Java, C++三种语言交叉混合的方式组成NativePlugin,然后使用Android或者iOS的SDK开辟子线程。

参考:
https://blog.csdn.net/qq_28180261/article/details/64500720
https://blog.csdn.net/Le11eL/article/details/123464876

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容

  • 一、【Unity3D】协程Coroutine的运用[https://blog.csdn.net/yongh701/...
    合肥黑阅读 10,340评论 0 3
  • 一:什么是协同程序? 答:在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行。换句话说,开启协程就是开启一...
    好怕怕阅读 3,880评论 2 23
  • 在这个降低入门门槛的大环境下,Unity 因为考虑到降低门槛,设计之初就是一个单线程,不允许在另外的线程中进行渲染...
    耳朵里有只风阅读 8,264评论 0 5
  • 一:什么是协同程序?答:在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行。换句话说,开启协程就是开启一个...
    CrixalisAs阅读 2,068评论 1 7
  • 一:什么是协同程序? 在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但是不是多线程,...
    胤醚貔貅阅读 2,077评论 0 13