停止协程
本课属于 Coddy Unity 学习旅程的“物理与游戏玩法”单元。第 26 课,共 71 课。
StartCoroutine 会返回一个 Coroutine,它是对已启动协程的引用。将它保存在字段中,StopCoroutine(handle) 会在协程暂停的位置停止它:yield 后面的代码行不会运行。StopAllCoroutines() 会停止脚本启动的所有协程。按空格键可以开启或关闭这个警报:
Coroutine beeping;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
if (beeping == null)
{
beeping = StartCoroutine(Beep());
}
else
{
StopCoroutine(beeping);
beeping = null;
}
}
}
IEnumerator Beep()
{
while (true)
{
Debug.Log("Beep");
yield return new WaitForSeconds(1f);
}
}协程停止时,字段不会自动清空,所以警报会将它重新设为 null,这样下次按空格键时就知道没有协程在运行。两种看起来正确的做法其实都不起作用。StopCoroutine(Beep()) 会再次调用 Beep(),这会创建一个尚未启动的新协程,然后停止它,因此警报会继续响。使用 enabled = false 会关闭脚本的 Update(),但协程会继续运行。协程在通过其引用停止、被 StopAllCoroutines() 停止、运行到最后一行,或者其 GameObject 通过 SetActive(false) 停用或被销毁时结束。
挑战
简单点击鼠标即可拆除炸弹,无需关闭脚本。
- 添加字段
Coroutine fuse;。按下 Space 时,设置fuse = StartCoroutine(Fuse());。 - 点击鼠标时,替换
enabled = false;:当fuse != null时,调用StopCoroutine(fuse);,设置fuse = null;,并记录Defused。
按“开始”,再按 Space,然后点击鼠标:控制台会显示 Defused,炸弹也会保留。然后点击“检查”。
亲手试试
using System.Collections;
using UnityEngine;
public class Bomb : MonoBehaviour
{
public float fuseTime = 3f;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(Fuse());
}
if (Input.GetMouseButtonDown(0))
{
enabled = false;
Debug.Log("Defused");
}
}
IEnumerator Fuse()
{
Debug.Log("Fuse lit");
yield return new WaitForSeconds(fuseTime);
Debug.Log("Boom");
Destroy(gameObject);
}
}
物理与游戏玩法中的所有课
自己练习: Unity 在线编辑器