定义:

Unity协程是一种协作式多任务机制,允许在主线程中分段执行代码,通过IEnmerator来实现,使用yield 语句暂停并在特定条件后恢复。可以实现异步操作。

特点:

  • 单线程:协程执行在主线程,与主线程共享执行环境,本质是代码执行顺序的控制,不需要处理线程安全问题。
  • 低开销:不用创建线程,通过迭代器模式(C#的IEnmerator实现)实现。
  • 非阻塞等待:适合处理异步操作(如加载资源,延迟执行),“伪并行”,除非协程中有耗时操作,否则不会阻塞主线程。

工作原理:

  1. 迭代器模式

    • 协程本质是实现了IEnmerator接口的迭代器。
    • 使用yield return语句定义暂停点,每次迭代返回一个条件对象(如 WaitForSeconds),Unity根据条件决定何时从暂停点继续执行。
  2. 执行流程

    • 启动协程,通过MonoBEhaviour对象的StartCoroutine()启动协程。
    • 执行到yield,执行到yield return 时,协程暂停,执行主线程逻辑。
    • Unity每帧检查协程的暂停条件(等待多长时间,或是当前帧结束),条件满足后从暂定点继续执行剩下逻辑。
  3. 生命周期

    • 协程依附于MonoBehaviour对象,如果对象被销毁(Destroy)或脚本被禁用(enabled = false),协程会自动终止。
    • 使用StopCoroutine()或StopAllCoroutines()去手动停止协程。

应用:

延迟处理,分帧加载资源,计时操作,逐渐更改物体颜色。

注意事项:

  1. 协程不是线程

    • 协程运行在主线程中,不可用于CPU密集型计算(如物理模拟,大规模数学计算),否则会阻塞主线程。
    • 若需并行计算,应使用线程(System.Threading.Thread)或任务(Task),但需在主线程中同步结果。
  2. 生命周期管理

    • 协程与MonoBehaviour对象绑定,若对象被销毁,协程自动终止。
    • 在OnDestroy()中手动停止协程,避免残留协程引用导致错误。
  3. 性能优化

    • 频繁创建/销毁协程可能产生GC开销,可复用协程或使用对象池。
    • 避免在协程内每帧执行复杂逻辑(如遍历大型列表)。
  4. 避免过度嵌套

    • 过度嵌套协程会增加代码复杂度,建议用yield return StartCoroutine() 简化逻辑。

协程嵌套:

协程的嵌套是通过在一个协程中启动协程并等待该协程完成的机制实现的。过度嵌套协程会导致代码可读性下降。

IEnumerator ParentCoroutine() {
    Debug.Log("父协程开始");
    
    // 启动并等待子协程完成
    yield return StartCoroutine(ChildCoroutine());
    
    Debug.Log("父协程继续");
}

IEnumerator ChildCoroutine() {
    Debug.Log("子协程开始");
    yield return new WaitForSeconds(1f);
    Debug.Log("子协程结束");
}

Unity协程背后实现的原理: 文档链接