Unity——延时执行的几种方法

1.什么是延迟函数

延时执行的函数,可以自己设定延时要执行的函数和具体延时的时间,是Monobehaviour基类中实现好的方法

1.Update定时器

在Update等刷新函数内计时,timer += Time.deltaTime 当时间达到预期,执行需要延时的方法。需要注意的是,增量时间Time.deltaTime是每帧都不同的浮点数。计时器不能用 == 去判断达成条件。需要用 > 或 >= 加一个标志位。以确保函数能执行到且只执行一次 Update在 Time.timeScale = 0 时会正常执行,但这时Time.deltaTime的值为0。

public class Test : MonoBehaviour
{
    public float timer = 0f;

    void Update()
    {
        timer += Time.deltaTime;
        if (timer >= 2)
        {
            Func();
            timer = 0f; // 定时2秒
        }
    }
    void Func()
    {
        Debug.Log("每2秒执行一次");
    }
}

2.Invoke函数

Invoke是MonoBehaviour提供的函数,可以延时调用函数,但是,Invoke的调用是在运行时生效的,对于Func函数,很容易导致在代码审查阶段被误杀—函数删除后,编译不会报错。Invoke支持重复调用: InvokeRepeating("方法名",延时时长,每次调用间隔时长)

public class Test : MonoBehaviour
{
    private float delayTime = 2;
    private void Start()
    {
        Invoke("Func", delayTime);
        //InvokeRepeating("DelayFunc",delayTime,cdTime);
    }
    private void Func()
    {
        Debug.Log("延迟2s执行该函数");
    }
}

取消延时函数: 

//取消延迟函数
//取消该脚本上的所有延时函数执行
CancelInvoke();

//指定函数名取消
//只要取消了指定延迟 不管之前该函数开启了多少次 延迟执行 都会统一取消
CancelInvoke(nameof(DelayDoSomething));

3.协程 Coroutine

协程本质是迭代器

public class Test : MonoBehaviour
{
    private void Start()
    {
        StartCoroutine(Show());
    }
    private IEnumerator Show()
    {
        yield return new WaitForSeconds(2);
        Func();
    }

    private void Func()
    {
        Debug.Log("延时2s执行");
    }
}

4.DoTween 方法实现

DoTween函数中提供了一个方法dotween.to函数

	/// <summary>
    /// DOTweenTo延时回调
    /// </summary>
    /// <param name="delayedTimer">延时的时间</param>
    /// <param name="loopTimes">循环次数,0:不循环;负数:无限循环;正数:循环多少次</param>
    public void DOTweenToTest(float delayedTimer, int loopTimes)
    {
        float timer = 0;
        //DOTwwen.To()中参数:前两个参数是固定写法,第三个是到达的最终值,第四个是渐变过程所用的时间
        Tween t = DOTween.To(() => timer, x => timer = x, 1, delayedTimer)
                      .OnStepComplete(() =>
                      {
                          print("调用函数");
                      })
                      .SetLoops(loopTimes);        
    }