在 Unity 中,我什么时候应该使用协程而不是在 Update() 中减去 Time.deltaTime?

Rog*_*ang 8 c# time ienumerator coroutine unity-game-engine

下面是我想强调的差异的一个简单示例。

使用协程:

public float repeatRate = 5f;
void Start()
{
    StartCoroutine("RepeatSomething");
}
IEnumerator RepeatSomething()
{
    while (true)
    {
        yield return new WaitForSeconds(repeatRate);
        // Do something
    }
}
Run Code Online (Sandbox Code Playgroud)

使用Update()Time.deltaTime

public float repeatRate = 5f;
private float timer = 0;
void Update()
{
    if (timer < 0)
    {
        // Do something
        timer = repeatRate;
    }
    timer -= Time.deltaTime;
}
Run Code Online (Sandbox Code Playgroud)

我什么时候应该使用一个而不是另一个,每个的优点/缺点是什么?

Jac*_*ani 9

大多数情况下答案是。

一般来说,Update 和 Coroutine 之间的性能差异并不相关。只需遵循最适合您的方法,但如果您想遵循类似协程的方法,请使用性能更高的MEC Coroutines方法Unity Coroutine

使用简单

正如统一论坛中所提到的,“对于Coroutines多个框架上执行方法很有用[然后忘记它]”。

如果您打算只使用其中的几个(少于 10k?),那么您也可以使用Unity Coroutines.

高级用法

目前Unity支持Task/Async,但性能仍然很低。所以你可能会考虑使用Coroutines来模拟Async功能。

在这种情况下,您甚至可以Coroutines删除所有(或大部分)Update循环,例如您发布的示例。

这在性能方面非常有用,尤其是在您的特定情况下,因为当您使用循环时,即使您什么都不做,Update您也会不断地检查。if (timer < 0)即使是空的更新循环仍然是一个性能问题。

另一方面,Coroutines当事件发生时,您可能只是开始和停止。当协程停止时,性能成本变为 0。

如果您想遵循此方法,我强烈建议使用MEC 协程,它可以消除 Unity 协程引起的所有性能问题(并具有相同的功能)。


综上所述

  1. 在大多数情况下,这种性能差异并不相关
  2. MEC Coroutines比更新循环的性能要好一些
  3. Update循环通常比Unity Coroutines
  4. Unity Coroutines应该只用于很少发生的简单定时任务

PS:这个关于统一协程的答案可能会帮助您深入了解它们是如何工作的。
PPS:这个旧答案可能会给您带来进一步的见解,但它有点过时了,特别是当它谈论垃圾收集时。


小智 5

只是想在这里发布,我最近尝试了 MEC 协程,如果我们检查延迟和响应时间,它比 Unity 协程性能更高,但只有当您运行如此多的协程(例如至少超过 10K 的简单协程)时才重要),很可能你永远不会或不应该。然而,从那时起,GC 与 Unity 协程的工作就被修复了,实际上 MEC 协程现在给 GC 带来了更多的工作,大约增加了 10 倍!因此,我用协程增加了一个数字,为​​新的协程增加了一个增量,就像开发人员在 2016 年所做的性能测试一样,Unity 的协程支持了 Playmode,但在我的情况下产生了 68MB 垃圾,而 MEC 则产生了垃圾0,73GB...所以我把我的协程改回Unity的。