Unity中的Update与FixedUpdate

一:前言

例如一个RPG游戏,主角的移动通过在Update中用速度乘以时间差Time.deltaTime模拟,当某帧卡顿了很久,Time.deltaTime将会变得很大,导致下一帧主角会无视地图障碍直接瞬移到一个很远的距离导致穿模,超出地图等bug,而在FixedUpdate中会避免此问题,下面就针对Update与FixedUpdate深入研究一下


二:区别

Unity的物理系统是通过FixedUpdate来执行的

——执行顺序
Update在FixedUpdate之后执行。例如有两个脚本A和B,A中有Update和FixedUpdate,B中有FixedUpdate,A中有Update会在A和B的FixedUpdate都执行后再执行


——执行时机
Update是每帧执行(每次渲染新的一帧的时候),与设备的性能和Update中逻辑的复杂程度有关,使用Time.deltaTime可以获取到与上一帧的时间差,Unity限定最大值为0.333秒
FixedUpdate也是每帧执行,但是它帧率固定(由Time设置中的Fixed Timestep参数决定 )


三:重点

一个逻辑帧(一次Update算一个逻辑帧)中可能会执行多次FixedUpdate,Fixed Timestep默认设置为0.02s,则一秒会准确执行50次FixedUpdate,而Update的执行次数会根据设备的帧率影响
例如Update中有很复杂的逻辑运算,当某帧卡顿了很久后,Update执行了一次,而FixedUpdate会执行很多次,它会将中间丢失的帧补回来,假设这一帧Time.deltaTime=0.1,则FixedUpdate会执行0.1/0.02=5次
Unity会将较大的帧间隔切分成多个固定的小时间段计算,但这种切分不能是无节制的,FixedUpdate中的运算也会带来计算负荷,如果为了追上帧间隔而带来太多FixedUpdate调用会让下一帧的时间更长,而更长的帧间距则需要更多的FixedUpdate来追上,这会导致一个恶行循环,所以FixedUpdate的调用会有一个时间限制,通过Time设置中的Maximum Allowed Timestep参数,这个参数表示两帧之间FixedUpdate计算的最长时间,当超过这个时间的帧间隔后FixedUpdate会停止计算,这样可以实现效果与性能的平衡
反之如果在FixedUpdate中执行复杂的逻辑运算,是非常可怕的,当某帧卡顿了很久后,Update执行了一次,Unity会执行多次的FixedUpdate来追上,而现在卡顿的根本是FixedUpdate而不是Update,例如需要执行16次FixedUpdate,而每次FixedUpdate又会造成卡顿,进入了恶行循环

using UnityEngine;

public class Test : MonoBehaviour
{
    int count = 0;
    private void FixedUpdate()
    {
        count++;
        Debug.Log("FixedUpdate " + count);
    }

    float timer = 0;
    private void Update()
    {
        int v = 999;
        for (int i = 0; i < 999999999; i++)
        {
            v += v * i;
        }
        timer += Time.deltaTime;
        Debug.Log(Time.deltaTime);
    }
}

猜你喜欢

转载自blog.csdn.net/LLLLL__/article/details/127770056