Unity之协程

协程(Coroutine)是 Unity 中一种可以暂停执行、稍后再继续 的特殊函数,它不是多线程,而是在主线程中执行的,只是通过yield关键字实现了 "分段执行" 的效果。

一、核心原理

  • 协程本质是一个返回值为IEnumerator的函数,通过yield return语句标记暂停点。
  • Unity 的主线程每帧会检查所有运行中的协程,当协程的暂停条件满足(比如等待 1 秒、等待帧结束),就会从暂停点继续执行后续代码。
  • 协程始终在主线程运行,因此不能用协程解决耗时计算(耗时操作需用多线程),但适合处理 "需要等待" 的逻辑(如等待动画播放、等待网络请求响应)。

二、协程的基础语法

1. 定义协程

协程函数必须满足:

  • 返回值为IEnumerator
  • 函数体中包含yield return语句
  • 函数名通常以StartXXX开头(约定俗成)
cs 复制代码
using UnityEngine;
using System.Collections; // 必须引入此命名空间

public class CoroutineDemo : MonoBehaviour
{
    // 定义一个简单的协程
    IEnumerator SimpleCoroutine()
    {
        Debug.Log("协程开始执行 - 第一帧");
        yield return null; // 暂停,下一帧继续执行
        
        Debug.Log("协程继续执行 - 第二帧");
        yield return new WaitForSeconds(2f); // 暂停2秒后继续
        
        Debug.Log("协程执行完毕 - 2秒后");
    }
}
2. 启动协程

通过StartCoroutine()方法启动协程,有两种方式:

cs 复制代码
void Start()
{
    // 方式1:直接传入协程函数(推荐,便于后续停止)
    StartCoroutine(SimpleCoroutine());
    
    // 方式2:传入字符串(性能稍差,只能停止该字符串对应的协程)
    StartCoroutine("SimpleCoroutine");
}
3. 停止协程

停止协程有 3 种常用方式:

cs 复制代码
// 方式1:停止指定的协程(需保存协程引用)
private Coroutine myCoroutine;
void Start()
{
    myCoroutine = StartCoroutine(SimpleCoroutine());
}
void StopMyCoroutine()
{
    StopCoroutine(myCoroutine);
}

// 方式2:停止当前脚本中所有协程
void StopAllMyCoroutines()
{
    StopAllCoroutines();
}

// 方式3:销毁挂载脚本的GameObject(协程会自动停止)
void DestroyGameObject()
{
    Destroy(gameObject);
}

三、常用的 yield 返回值(暂停条件)

协程的核心是yield return后的暂停条件,以下是最常用的类型:

|---------------------------------|------------------------------|--------------------------------------------------|
| 返回值 | 作用 | 示例 |
| null | 暂停 1 帧,下一帧继续 | yield return null; |
| WaitForSeconds(float) | 等待指定秒数(受 Time.timeScale 影响) | yield return new WaitForSeconds(1.5f); |
| WaitForSecondsRealtime(float) | 等待指定秒数(不受 Time.timeScale 影响) | yield return new WaitForSecondsRealtime(1.5f); |
| WaitForEndOfFrame() | 等待当前帧所有渲染完成后继续 | yield return new WaitForEndOfFrame(); |
| WaitForFixedUpdate() | 等待下一次 FixedUpdate 执行后继续 | yield return new WaitForFixedUpdate(); |
| WWW /UnityWebRequest | 等待网络请求完成(Unity 旧 / 新接口) | yield return webRequest.SendWebRequest(); |
| AnotherCoroutine() | 等待另一个协程执行完毕 | yield return AnotherCoroutine(); |

案例 :分步执行动画 / 逻辑

cs 复制代码
using UnityEngine;
using System.Collections;

public class StepByStepLogic : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(ExecuteStepByStep());
    }

    IEnumerator ExecuteStepByStep()
    {
        // 第一步:播放开门动画
        Debug.Log("播放开门动画");
        yield return new WaitForSeconds(2f); // 等待动画播放完毕
        
        // 第二步:移动角色到指定位置
        Debug.Log("移动角色");
        yield return new WaitForSeconds(1.5f);
        
        // 第三步:播放拾取物品动画
        Debug.Log("拾取物品");
        yield return new WaitForSeconds(1f);
        
        // 第四步:完成所有操作
        Debug.Log("任务完成");
    }
}
相关推荐
WiChP7 小时前
【V0.1B15】从零开始的2D游戏引擎开发之路
游戏引擎
zhchyun20082 天前
# 【Unity UI 进阶】仿 Element UI 打造企业级 Unity UI 组件库(06)
ui·unity·游戏引擎
Behaviour2 天前
Unity游戏HybridCLR 热更新接入实战
游戏·unity·游戏引擎
LONGZETECH3 天前
新能源汽车动力电池实训教学痛点与虚拟仿真技术解决方案
c语言·3d·unity·架构·汽车·汽车教学软件
王维志3 天前
UiSplineRenderer
unity·游戏引擎
k4m7v2pz3 天前
Godot 4 仿 agar.io:相机缩放被 max_zoom 卡死,窗口越大球越小的根因与修复
游戏引擎·godot·相机·缩放·clamp·camera2d
FairGuard手游加固3 天前
iOS 游戏加固技术解析:代码混淆、资源加密、内存保护与重签名检测
安全·游戏·macos·unity·ios·objective-c
k4m7v2pz3 天前
Godot 4 窗口拉伸黑边与变形:stretch 配置全解析
数码相机·游戏引擎·godot·2d游戏·黑边·stretch·画面比例
UWA4 天前
GPM 2.0 WebGL 监测能力扩容|覆盖 Unity/Cocos/LayaAir 多引擎微信 & 抖音小游戏
unity·微信·性能优化·小游戏·webgl
Behaviour4 天前
Unity 手游网络同步技术
网络·unity·c#·游戏引擎