如何理解Unity中Time.deltatime

首先,Time.deltatime通常在Update()方法中被调用

Update()方法的特性便是每帧执行一次,而Update()调用的速率与帧速率有关,而帧速率是不断变化的,帧速率的高低与设备本身性能和系统繁忙程度都有关系。

举个通俗的例子

    void Update()
    {
        player.transform.Translate(new Vector3(0,0,1));        
    }

这是实现玩家向前移动的基本代码,它的基础逻辑便是使游戏物体在原有的位置上发生移动,移动方向是Vector3所指的方向z轴,目的位置是Vector3的位置,即

transform.position = transform.position + Vector3;

由此才能每一帧都向z轴正方向移动一个单位,达到比较连贯的移动效果,倘若把这行移动代码放在Start()方法中,那么它的z轴仅仅朝正方向移动一个单位后就会停下来即仅调用一次。

相信大家玩第一人称射击游戏或者英雄联盟的时候都会看到一个关键的面板:FPS,并且后面会有跳动的数值,并且都说数值越高,帧率越高。这个说法倒也没多大问题,FPS全称Frame Per Second,英译过来便是画面每秒传输的帧数。

因此,倘若一台电脑的实时FPS为80,那么每秒就会调用Update()方法80次,同样对应的1秒钟内这个游戏物体的z轴会移动80个单位长度。

但是,倘若别人由于设备问题导致实时FPS只有50,那么每秒就只能调用Update()方法50次,1秒钟内z轴也只能移动50个单位长度。即相同的代码,同一秒内,硬件好的比硬件差的多走了30个单位长度,那么硬件差的人就直接脱口而出“这游戏狗都不玩...”了。

另外还有一个问题,相信玩游戏的人都经历过所谓的“跳帧”情况,即FPS忽高忽低,极为不稳定,这就会导致原本FPS80的玩家移动起来速度一下快一下慢,即上一秒移动80个单位,下一秒移动30个单位,极为折磨,旋转效果更是鬼畜抽动,最后就也说“这游戏狗都不玩...”了。

为了解决上述问题,Time.deltatime出现了,Time.deltatime表示距上一次调用Update()所用的时间,即时间增量,单位是毫秒(ms),倘若使用了Time.deltatime

    void Update()
    {
        player.transform.Translate(new Vector3(0,0,1)*Time.deltaTime);        
    }

那么就能使Update()中的这个移动行为看起来与帧速率无关,没加Time.deltatime的时候代表每帧向z轴正方向移动1个单位,加了后代表每秒移动1个单位。

为什么Time.deltatime可以实现这个效果呢?

假设一台实时FPS稳定且为80的电脑,它在1秒钟内就会闪过80帧画面,那么播放这80帧过程中的每一个时间间隔都是deltatime,那么就意味着每一帧内,游戏物体都能走1/80个单位长度,所以1秒走一个单位长度。

那么另一台实时FPS稳定且为50的电脑,它在1秒钟内闪过50帧画面,那么每一帧画面游戏物体能走1/50个单位长度,那最终也是1秒走完一个单位长度。

即不论1秒钟内分了多少帧,不论实时FPS稳不稳定,这一秒钟内的deltatime的和是一样的,都为1,所以一秒钟内的位移变化也是相同的。

因此,我们使用的过程中,以后想要游戏物体一秒移动多少个单位长度,那么仅需

一秒需要移动的单位长度*Time.deltatime

为什么不把移动代码写进FixedUpdate()方法中呢?

相信有一定实践基础的同学都知道下面这三个常用的Update()方法

Update()每帧调用就不多说了,LateUpdate()在所有的Update()方法执行完后再执行,通常在做相机跟随时会使用,即角色动了相机才动,这里也就不细说了;

FixedUpdate()每秒调用次数是一定的,但每帧调用的次数不是一定的,因游戏中每帧时间不一样,如果一帧计算的东西太多或者画面太复杂,这一帧的时间可能会比较长。

在unity中,初始固定更新的时间是0.02s,1秒执行50次,但是FixedUpdate的时间间隔可以在项目设置中更改,Edit->Project Setting->time 找到Fixed timestep,就可以修改,所以这种固定更新方法,和物理相关的操作代码写在其中会很方便。

相信大家看到这就猜到了这个问题的答案,没错,如果我们用了FixedUpdate()方法且默认更新参数,那么我们就把移动这个行为的FPS固定在了50,如果我们电脑的实时FPS偏高或者偏低,那么位移的长度也会按照比例改变,从而才能保证匀速的变化,因为它一帧的时间不确定,所以要按1帧的时间来实时调整的位移大小来保持速度不变,这样就会影响玩家的游戏体验,所以用Update()方法来实现这类功能实现会好一些。

猜你喜欢

转载自blog.csdn.net/knight209208/article/details/128515995
今日推荐