Unity中的FixedUpdate、Update、LateUpdate的区别及游戏帧更新

【基本了解】

  • 三者执行顺序:FixedUpdate ——>Update ——>LateUpdate
  • 三者作用:FixedUpdate固定帧更新,一般用作物理更新;Update一般用作游戏逻辑更新;LateUpdate一般用作相机更新

【深入了解】

  • 帧率的概念

帧率是什么呢?一秒内画面更新的次数。游戏常用的有30fps,60fps。我们知道,帧率低游戏会卡顿,具体解释下就是,每秒内看到的画面更新次数变少,少于一个阈值,那么画面在人眼看来就是不连续的,也即卡顿的。

这是阈值是多少呢?人眼识别的帧率一般在24fps~30fps之间,不同人有所差别,也就是说只有在一秒内更新的次数(即帧率)大于这个值,在人眼看来画面才会是连续的。

  • Update的帧率

游戏帧率不是恒定的,Update函数的调用次数也不是恒定的。这意味着什么呢?以30fps为例,其表示每秒画面更新30次。

虽然有的游戏号称是30fps,但真的是每秒画面更新30次,一分钟更新30*60次,一小时更新30*60*60次吗?

肯定不是的,影响游戏帧率的因素有很多,也许在某一秒内画面更新了30次,在某一秒内只更新了25次。

暂且简单地认为画面更新次数和Update调用次数等同,虽然两者并不等同。

也即某一秒内Update的的调用次数可能是30次,也可能是25次。在程序执行中,一般是这个方法执行完了之后才去执行下一个方法,这也意味着,每次调用Update方法时,执行完Update的时间是不一样的。这有什么影响呢?

例如,想让物体每秒移动30米,如果你按照固定帧率来的话,可以计算出每帧(即1/30s)移动的距离为1米。然后在Update中更新物体的位移,写下代码A:  transform.Translate(0, 0, 1)。这会发生什么呢?显然,可能会看到物体每秒移动的距离可能并不是30米,这是因为Update并不是每秒都调用30次。

(注意帧和秒的差别,从计算机的角度来看,是以帧来算画面的;从人的角度看,是以秒来算画面的)

所以,在Update中,我们常用Time.deltaTime,其表示完成上一帧所用时间(单位为秒)。写下代码B:transform.Translate(0, 0, 30*Time.deltaTime),则我们会看到每秒移动的距离基本上是30米。

仔细体会,你会发现,A实际上是将1s等分30份,每份时间都是1/30秒;B是将1s分为若干时间长度不同的多份,每份的Time.deltaTime的值都不一样,Unity内部会更新这个值。

  • FixedUpdate

在FixedUpdate中,我们常用Time.fixeddeltaTime,这是一个固定的值,可以在Edit->ProjectSetting->time —>Fixedtimestep中设置。所以,FixedUpate每秒调用次数是一定的,但每帧调用的次数不是一定的,因游戏中每帧时间不一样。

Unity中默认fixeddeltaTime为0.02秒,但FixedUpdate并不是真的就0.02秒调用一次。因为在脚本的生命周期内,FixedUpdate处有一个小循环,这个循环也是通过物理时间累积看是不是大于0.02了,然后调用一次。有很多物体都进行物理更新,那么FixedUpdate的调用也会慢下来。

  • LateUpdate

LateUpdate在所有的Update执行完后再执行。例如,有两个脚本,X中有Update和LateUpdate,Y有Update,那么会执行完X和Y的Update后再执行X的LateUpdate。相机跟随角色时,一般是等角色移动好了,再把相机移动过去,否则相机移动过去了,角色还没过来,游戏画面中就看不到角色。

那么能不能把相机更新放在Update方法最后面再执行呢?不能

一是因为多个脚本的Update的执行顺序不确定,怎么能保证相机所在的Update一定是最后执行呢。如果相机所在的Update先执行了,那么就会导致有些物体(包括角色、怪物等)没能进入画面。

二是因为Unity将内部动画的逻辑更新放在了Update和LateUpdate之间,相机更新放在Update中,那么角色的动画状态还没更新。

  • 游戏帧更新

上文说的帧是游戏画面更新算一帧a,而打开在Asset下新建的脚本会发现在Update前注释了“Update每帧b调用一次”。注意帧a和帧b不是一个意思,后者将Unity一个生命周期算作一帧。

显示器能支持的画面更新有一定限制,假设最大是50fps,即使在游戏中画面渲染可以达到60fps,那么画面更新仍然是50fps。我们常说的游戏帧率指的是画面渲染的帧率,而游戏中一个渲染画面的形成可能是多个帧b的结果。

【参考】

https://docs.unity.cn/cn/current/Manual/TimeFrameManagement.html

你可能感兴趣的:(Unity,FixedUpdate,Update,LateUpdate)