< 返回教程列表
3.5 协程 Coroutine
知识介绍
协程 = 可以"暂停执行并在下一帧继续"的函数,用于"需要等待/分多帧执行"的逻辑。
using UnityEngine;
using System.Collections; // 协程需要这个命名空间
public class CoroutineDemo : MonoBehaviour
{
private void Start()
{
// 启动协程
StartCoroutine(TestCoroutine());
}
// 协程方法:返回 IEnumerator
IEnumerator TestCoroutine()
{
Debug.Log("协程开始");
yield return null; // 暂停一帧
Debug.Log("过了1帧");
yield return new WaitForSeconds(2); // 暂停2秒
Debug.Log("又过了2秒");
// 等待另一个协程结束
yield return StartCoroutine(AnotherCoroutine());
Debug.Log("另一个协程结束了,这个也结束");
}
IEnumerator AnotherCoroutine()
{
yield return new WaitForSeconds(1);
Debug.Log("另一个协程:1秒");
}
// ============ 停止协程 ============
private Coroutine _myCo;
void StartAndStop()
{
_myCo = StartCoroutine(TestCoroutine()); // 保存引用
StopCoroutine(_myCo); // 按引用停
StopAllCoroutines(); // 全停
}
}
常用 yield 语句:
| yield 写法 | 作用 |
|---|---|
yield return null; |
等下一帧 |
yield return new WaitForSeconds(n); |
等 n 秒 |
yield return new WaitForFixedUpdate(); |
等下一次 FixedUpdate |
yield return new WaitForEndOfFrame(); |
等帧渲染结束 |
yield return StartCoroutine(Co()); |
等另一个协程结束 |
yield break; |
提前退出协程 |
例题
例题1: 倒计时 3、2、1 后爆炸(销毁 GameObject)。
IEnumerator CountdownBomb()
{
for (int i = 3; i >= 1; i--)
{
Debug.Log($"爆炸倒计时:{i}");
yield return new WaitForSeconds(1);
}
Debug.Log("Boom!");
Destroy(gameObject);
}
例题2: 按打字机效果逐字输出字符串。
IEnumerator TypeText(string text, float interval = 0.1f)
{
string result = "";
foreach (char c in text)
{
result += c;
Debug.Log(result); // 实际项目可以给 UI Text.text 赋值
yield return new WaitForSeconds(interval);
}
}
// 调用:StartCoroutine(TypeText("Hello Unity!"));
例题3: 场景逐渐淡出(循环修改颜色)。
IEnumerator FadeOut(SpriteRenderer sr, float duration)
{
float t = 0;
Color original = sr.color;
while (t < duration)
{
t += Time.deltaTime;
float a = Mathf.Lerp(1, 0, t / duration);
sr.color = new Color(original.r, original.g, original.b, a);
yield return null;
}
}
练习题
用协程写一个彩虹灯:Cube 的颜色 每秒 自动切换一种颜色(至少5种颜色循环)。
用协程做"闪现特效":
OnCollisionEnter触发时,把物体Renderer.material.color变成白色,等 0.1 秒再恢复原色(比如被击中闪白)。做一个 DOTween 风格的协程方法:
IEnumerator MoveTo(Transform t, Vector3 target, float duration),在 duration 秒内线性移动到 target 位置。用协程实现一个"轻攻击 + 重攻击 + 连招":按 J 键启动一个协程,0.5秒内再按 J 触发第二击,0.5秒再按触发第三击,超过 0.5 秒没按就重置。