协同力量

用法

如果你的长时间运行操作依赖于非线程安全的 Unity API,请使用 Coroutines 将其拆分为多个帧并使应用程序保持响应。

协同程序还帮助每第 n 帧执行昂贵的操作,而不是每帧执行该操作。

在多个帧上拆分长时间运行的例程

协同程序有助于在多个帧上分配长时间运行的操作,以帮助保持应用程序的帧速率。

在程序上绘制或生成地形或产生噪声的例程可能需要 Coroutine 处理。

for (int y = 0; y < heightmap.Height; y++) 
{
    for (int x = 0; x < heightmap.Width; x++)
    {
        // Generate pixel at (x, y)
        // Assign pixel at (x, y)
        
        // Process only 32768 pixels each frame
        if ((y * heightmap.Height + x) % 32 * 1024) == 0)
            yield return null; // Wait for next frame
    }
}

上面的代码是一个易于理解的例子。在生产代码中,最好避免每像素检查检查何时到 yield return(可能每 2-3 行执行一次)并预先计算 for 循环长度。

不经常执行昂贵的操作

协同程序可以帮助你不那么频繁地执行昂贵的操作,因此它不会像每帧执行时那样大。

直接从手册中获取以下示例 :

private void ProximityCheck() 
{
    for (int i = 0; i < enemies.Length; i++) 
    {
        if (Vector3.Distance(transform.position, enemies[i].transform.position) < dangerDistance)
                return true;
    }
    return false;
}

private IEnumerator ProximityCheckCoroutine() 
{
    while(true) 
    {
        ProximityCheck();
        yield return new WaitForSeconds(.1f);
    }
}

通过使用 CullingGroup API, 可以进一步优化接近度测试。

常见的陷阱

开发人员犯的一个常见错误是访问协同程序之外的协同程序的结果或副作用。一旦遇到 yield return 语句,协同程序就会将控制权返回给调用者,并且可能尚未执行结果或副作用。要避免必须在协程外使用结果/副作用的问题,请检查此答案