协程是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)
嵌套协程,等待另一个协程完成后继续。

最低0.47元/天 解锁文章
2387

被折叠的 条评论
为什么被折叠?



