unity基础之协程

关键点

  • 协程不是线程。 在协程中运行的同步操作仍然在主线程上执行。 如果您想减少花在主线程上的 CPU 时间,避免协程中的阻塞操作与在任何其他脚本代码中一样重要。

  • 如果您需要处理长时间的异步操作,例如等待 HTTP 传输、资产加载或文件 I/O 完成,最好使用协程。


样例

IEnumerator Fade()
{
    Color c = renderer.material.color;
    for (float alpha = 1f; alpha >= 0; alpha -= 0.1f)
    {
        c.a = alpha;
        renderer.material.color = c;
        yield return null;
    }
}

void Update()
{
    if (Input.GetKeyDown("f"))
    {
        StartCoroutine(Fade());
    }
}

停止协程

  • 要停止协程,请使用 StopCoroutine 和 StopAllCoroutines

  • 如果您将 SetActive 设置为 false 以禁用游戏对象,协程也会停止

  • 调用 Destroy(example)(其中 example 是一个 MonoBehaviour 实例)会立即触发 OnDisable 并且 Unity 会处理协程,从而有效地停止它。 最后,在帧结束时调用 OnDestroy。


分析协程

  • 协程的执行方式与其他脚本代码不同。 Unity 中的大多数脚本代码出现在特定回调调用下方的单个位置的性能跟踪中。 但是,协程的CPU代码总是在一个trace中出现在两个地方。

  • 每当调用 StartCoroutine 方法时,最常出现的初始代码。 Unity 回调生成的协程(例如返回 IEnumerator 的 Start 回调)首先出现在它们各自的 Unity 回调中。协程的其余代码(从第一次恢复到完成执行)出现在 Unity 主循环内的 DelayedCallManager 行中。

  • 发生这种情况是因为 Unity 执行协程的方式。 C# 编译器自动生成支持协程的类的实例。 Unity 然后使用此对象跨单个方法的多次调用跟踪协程的状态。 因为协程中的局部作用域变量必须在 yield 调用中保持不变,Unity 将局部作用域变量提升到生成的类中,这些变量在协程期间保持分配在堆上。 该对象还跟踪协程的内部状态:它记住协程在屈服后必须在代码中的哪一点恢复。

  • 协程启动时发生的内存压力等于固定开销分配加上其局部范围变量的大小。

  • 启动协程的代码构造并调用一个对象,然后只要满足协程的 yield 条件,Unity 的 DelayedCallManager 就会再次调用它。 因为协程通常在其他协程之外启动,所以这将它们的执行开销分摊到 yield 调用和 DelayedCallManager 之间。

猜你喜欢

转载自blog.csdn.net/a_codecat/article/details/128135876