Menu
CoddyTech

Dừng Coroutine

Thuộc phần Vật lý và lối chơi trong hành trình Unity của Coddy. Bài học 26 trên 71.

StartCoroutine trả về một Coroutine, một tham chiếu đến coroutine mà nó đã bắt đầu. Hãy lưu tham chiếu này vào một trường, rồi gọi StopCoroutine(handle) để dừng coroutine đó tại chỗ nó đang tạm dừng: các dòng sau yield sẽ không bao giờ chạy. StopAllCoroutines() dừng mọi coroutine mà tập lệnh đã bắt đầu. Nhấn Space để bật hoặc tắt báo thức này:

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);
    }
}

Trường này không tự xóa khi coroutine dừng, nên báo thức đặt lại giá trị của nó thành null. Nhờ vậy, lần nhấn Space tiếp theo biết rằng không có coroutine nào đang chạy. Có hai cách trông có vẻ đúng nhưng lại không hoạt động. StopCoroutine(Beep()) gọi Beep() lần nữa, tạo ra một coroutine mới chưa được khởi chạy rồi dừng coroutine đó, nên báo thức vẫn tiếp tục kêu. Còn enabled = false tắt Update() của tập lệnh, nhưng các coroutine vẫn tiếp tục chạy. Coroutine kết thúc khi bạn dừng nó bằng tham chiếu hoặc bằng StopAllCoroutines(), khi nó chạy đến dòng cuối cùng, hoặc khi bạn vô hiệu hóa GameObject bằng SetActive(false) hoặc hủy nó.

challenge icon

Thử thách

Dễ

Nhấp chuột để gỡ ngòi bom mà không tắt tập lệnh.

  1. Thêm một trường Coroutine fuse;. Khi nhấn Space, gán fuse = StartCoroutine(Fuse());.
  2. Khi nhấp chuột, thay enabled = false;: khi fuse != null, gọi StopCoroutine(fuse);, gán fuse = null; và ghi nhật ký Defused.

Nhấn Chơi, nhấn Space, rồi nhấp chuột: Console hiển thị Defused và quả bom vẫn còn đó. Sau đó nhấn Kiểm tra.

Tự làm thử

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);
    }
}

Tất cả bài học trong Vật lý và lối chơi

Tự luyện tập: Playground Unity