Unity的TimeScale的影响范围分析

大家好,我是阿赵。
这期来说一下Unity的TimeScale。

一、前言

  Unity提供了Time这个类,来控制时间。其实我自己倒是很少使用这个Time,因为做网络同步的游戏,一般是需要同步服务器时间,所以我比较多是在使用System.DateTime获取系统时间,再定一个时间间隔和服务器同步当前时间,来维持一个客户端和服务器的时间同步。
  不过Unity的Time方法也是有比较有用的时候,特别是Time.timeScale时间缩放这个属性,它可以整体的加快或者减慢甚至暂停Unity里面动画播放。
  不过这个TimeScale,也是会引起一些问题的,所以在使用之前,必须对它的影响范围做一个详细了解。

二、Demo

  TimeScale对Unity的所有动画组件都是起作用的,包括了Animation、Animator、粒子发射器等。接下来看看它对脚本运行的影响。
  这里写一个简单的Demo,实际看看TimeScale的变化时,一些我们比较关心的方法调用有什么影响。

using UnityEngine;

public class TestTimeScale : MonoBehaviour
{

    private float passTime = 0;
    private float fixedPassTime = 0;
    private float updateTime = 0;
    private float fixedUpdateTime = 0;
    private float lateUpdateTime = 0;
    private float[] timeArray = new float[] { 0, 0.1f, 1, 3 };
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        passTime += Time.deltaTime;
        updateTime += 1;
    }

    void FixedUpdate()
    {
        fixedPassTime += Time.fixedDeltaTime;
        fixedUpdateTime += 1;
    }
    private void LateUpdate()
    {
        lateUpdateTime += 1;
    }

    void OnGUI()
    {
        GUILayout.BeginHorizontal();
        GUILayout.Box(Time.timeScale + "");
        for(int i = 0;i<timeArray.Length;i++)
        {
            if(OneButton(timeArray[i] + "x"))
            {
                Time.timeScale = timeArray[i];
            }
        }
        GUILayout.EndHorizontal();
        GUILayout.Label("Time.time:"+Time.time);
        GUILayout.Label("passTime:" + passTime);
        GUILayout.Label("fixedPassTime:" + passTime);
        GUILayout.Label("updateTime:" + updateTime);
        GUILayout.Label("fixedUpdateTime:" + fixedUpdateTime);
        GUILayout.Label("lateUpdateTime:" + lateUpdateTime);
        GUILayout.Label("Time.deltaTime:" + Time.deltaTime);
        GUILayout.Label("Time.fixedDeltaTime:" + Time.fixedDeltaTime);
        GUILayout.Label("Time.fixedTime:" + Time.fixedTime);
        GUILayout.Label("Time.fixedUnscaledDeltaTime:" + Time.fixedUnscaledDeltaTime);
        GUILayout.Label("Time.realtimeSinceStartup:" + Time.realtimeSinceStartup);
    }

    private bool OneButton(string content)
    {
        return GUILayout.Button(content, GUILayout.Width(100), GUILayout.Height(40));
    }
}

在这里插入图片描述

  运行demo,会看到上面有几个调整TimeScale的按钮,分别把TimeScale设置成0、 0.1 、1 、3。然后下面有一些当前数值的变化显示。

三、分析

1、Update类

1.Update

  通过观察demo里面的updateTime 可以发现,Update方法的调用频率,是不会受到TimeScale的变化的影响的。

2.FixedUpdate

  通过观察demo里面的fixedUpdateTime 可以发现,FixedUpdate方法是受到TimeScale影响的,当TimeScale变成0的时候,值就不会增长了,当TimeScale值变大那时,调用的频率也会变快。

3.LateUpdate

  通过观察demo里面的lateUpdateTime 可以发现,LateUpdate方法调用不受TimeScale的影响。

2、时间运行类

1.Time.time

  这个时间是从开始游戏到当前帧开始的时间,从demo运行可以看出,这个时间是会受到TimeScale的影响的,当TimeScale变成0的时候,它就不会增长了。

2.Time.fixedTime

  这个时间是从游戏开始运行到最后一次FixedUpdate方法调用的时间,从上面可以指定,FixedUpdate是受到TimeScale的影响的,所以,Time.fixedTime同样也会受到TimeScale的影响。

3.Time.realtimeSinceStartup

  这个时间是从游戏开始运行到当前的实际时间。从demo可以看出,这个时间是不会受到TimeScale的影响的。所以如果想做一个不受TimeScale影响的计时器,可以使用这个。不过我还是更习惯于使用系统时间。

3、时间间隔类

1.Time.deltaTime

  这个时间是从上一帧到当前帧所过的时间。我们经常会使用speedTime.deltaTime来做一些准确限制速度的程序动画。
  从demo可以看出,Time.deltaTime是会受到TimeScale的影响的,TimeScale的值越大,Time.deltaTime的值也就越大。所以通过在UpDate方法里面计算speed
Time.deltaTime来做动画时,当调大了TimeScale的值,那么动画的速度也会变快。

2.Time.fixedDeltaTime

  从demo可以看出,Time.fixedDeltaTime是不会受到TimeScale的影响的,它默认是0.02,然后我们调节TimeScale的值,Time.fixedDeltaTime是不会变化的。
  值得注意的是,上面列举的所有参数,都是只读的,但是Time.fixedDeltaTime却是可读写的。这个是非常有意义的事情来的。如果我们使用speedTime.deltaTime来做动画,动画会跟随这TimeScale变快,但如果我们有一部分动画的速度不想跟随着TimeScale变化,那么就可以用speedTime.fixedDeltaTime来计算。而且我们还可以自己调节fixedDeltaTime的值,来单独控制这部分动画的快慢。

猜你喜欢

转载自blog.csdn.net/liweizhao/article/details/132352939