Unity协程(Coroutine)详解

协程是Unity中一种强大的编程工具,它允许你在不阻塞主线程的情况下执行跨越多个帧的操作。协程提供了一种优雅的方式来处理需要随时间推移执行的任务,如动画、延时操作、分步骤处理等。

1. 协程的基本概念

什么是协程?

协程是一种特殊的函数,它可以在执行过程中暂停(yield),然后在之后的某个时间点恢复执行。这与普通函数不同,普通函数一旦开始执行就会一直运行到完成。

协程的关键特性:

  • 可以暂停执行并在之后恢复
  • 不会阻塞主线程
  • 使用yield语句来指示暂停点
  • 返回类型必须是IEnumerator
  • 必须使用StartCoroutine()方法启动

协程与线程的区别

协程不是线程。关键区别:

  • 协程在主线程上运行,不是并行执行
  • 协程没有线程切换的开销
  • 协程不需要线程同步机制
  • 协程是协作式多任务处理,而不是抢占式

2. 协程的基本语法

定义协程

private IEnumerator MyCoroutine()
{
    Debug.Log("协程开始");
    
    // 等待5秒
    yield return new WaitForSeconds(5f);
    
    Debug.Log("5秒后继续执行");
    
    // 等待下一帧
    yield return null;
    
    Debug.Log("在下一帧继续执行");
}

启动协程

void Start()
{
    // 方法1:直接启动
    StartCoroutine(MyCoroutine());
    
    // 方法2:通过字符串名称启动(不推荐,因为没有编译时检查)
    StartCoroutine("MyCoroutine");
    
    // 方法3:保存协程引用以便之后停止
    Coroutine coroutineHandle = StartCoroutine(MyCoroutine());
}

停止协程

// 方法1:通过协程引用停止特定协程
Coroutine coroutineHandle = StartCoroutine(MyCoroutine());
StopCoroutine(coroutineHandle);

// 方法2:通过方法引用停止
StopCoroutine(MyCoroutine());

// 方法3:通过字符串名称停止(不推荐)
StopCoroutine("MyCoroutine");

// 方法4:停止所有协程
StopAllCoroutines();

3. 协程的yield指令

协程使用yield return语句来指定暂停点和恢复条件。Unity提供了多种内置的yield指令:

yield return null

等待到下一帧的Update函数执行完毕后继续。

IEnumerator WaitForNextFrame()
{
    Debug.Log("当前帧");
    yield return null;
    Debug.Log("下一帧");
}

yield return new WaitForSeconds(float seconds)

等待指定的秒数后继续。这个时间是受Time.timeScale影响的。

IEnumerator WaitForFiveSeconds()
{
    Debug.Log("开始等待");
    yield return new WaitForSeconds(5f);
    Debug.Log("5秒后");
}

yield return new WaitForSecondsRealtime(float seconds)

等待指定的秒数,但不受Time.timeScale影响(真实时间)。

IEnumerator WaitRealtime()
{
    Time.timeScale = 0.5f; // 游戏时间减慢
    Debug.Log("开始等待真实时间");
    yield return new WaitForSecondsRealtime(5f);
    Debug.Log("5秒真实时间后"); // 无论timeScale如何,都是5秒后执行
}

yield return new WaitForFixedUpdate()

等待到下一次FixedUpdate执行完毕后继续。

IEnumerator WaitForPhysicsUpdate()
{
    Debug.Log("等待物理更新");
    yield return new WaitForFixedUpdate();
    Debug.Log("物理更新后");
}

yield return new WaitForEndOfFrame()

等待到当前帧中的所有摄像机和GUI渲染完成后继续。

IEnumerator CaptureScreenshot()
{
    Debug.Log("准备截图");
    yield return new WaitForEndOfFrame();
    // 此时所有渲染已完成,适合截图
    ScreenCapture.CaptureScreenshot("screenshot.png");
    Debug.Log("截图完成");
}

yield return new WaitUntil(Func<bool> predicate)

等待直到指定的条件变为true。

private bool isConditionMet = false;

IEnumerator WaitForCondition()
{
    Debug.Log("等待条件满足");
    yield return new WaitUntil(() => isConditionMet);
    Debug.Log("条件已满足");
}

// 在其他地方设置条件
public void SetCondition()
{
    isConditionMet = true;
}

yield return new WaitWhile(Func<bool> predicate)

等待直到指定的条件变为false。

private bool isProcessing = true;

IEnumerator WaitForProcessToComplete()
{
    StartProcess();
    Debug.Log("等待处理完成");
    yield return new WaitWhile(() => isProcessing);
    Debug.Log("处理已完成");
}

private void StartProcess()
{
    // 启动某个处理过程
    // 在处理完成时设置 isProcessing = false
}

yield return StartCoroutine(IEnumerator routine)

嵌套协程,等待另一个协程完成后继续。


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值