Menu
CoddyTech

Vòng lặp trong 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 25 trên 71.

Vòng lặp có yield return bên trong sẽ chạy qua nhiều khung hình, vì mỗi lần lặp đều tạm dừng trước lần tiếp theo. Với WaitForSeconds, vòng lặp lặp lại một việc theo nhịp. Còi báo động này nhấp nháy 3 lần:

IEnumerator Flash()
{
    for (int i = 0; i < 3; i++)
    {
        lamp.enabled = true;
        yield return new WaitForSeconds(0.2f);
        lamp.enabled = false;
        yield return new WaitForSeconds(0.2f);
    }
}

Với yield return null, vòng lặp thực hiện một chút việc trong mỗi khung hình cho đến khi thỏa mãn điều kiện. Đây là cách coroutine tạo hoạt ảnh cho một đối tượng. Quả bóng bay này, ban đầu có tỷ lệ là 1, tăng 0.5 mỗi giây cho đến khi tỷ lệ đạt 2, rồi hiển thị:

IEnumerator Inflate()
{
    while (transform.localScale.x < 2f)
    {
        transform.localScale += Vector3.one * 0.5f * Time.deltaTime;
        yield return null;
    }
    Debug.Log("Full");
}

Time.deltaTime hoạt động ở đây giống như trong Update(): coroutine tiếp tục chạy một lần mỗi khung hình, và dòng lệnh sau vòng lặp chỉ chạy khi vòng lặp kết thúc. Nếu không có yield, toàn bộ vòng lặp sẽ chạy trong một khung hình và quả bóng bay sẽ phồng lên đầy ngay lập tức. Vòng lặp while (true) dùng trong coroutine vẫn ổn, miễn là mỗi lần lặp đều có lệnh yield; nếu không có yield, vòng lặp không bao giờ nhường lại khung hình và trình soạn thảo Unity sẽ bị treo.

challenge icon

Thử thách

Dễ

Viết Ride để cổng kéo thực hiện một chuyến đi trọn vẹn.

  1. Đặt Vector3 up = down + Vector3.up * height;. Khi while (transform.position != up), di chuyển bằng Vector3.MoveTowards(transform.position, up, speed * Time.deltaTime) và yield return null;.
  2. Ghi nhật ký Open, rồi yield return new WaitForSeconds(1f);.
  3. Di chuyển vòng lặp xuống lại down theo cách tương tự, rồi ghi nhật ký Closed.

Nhấn Chơi rồi nhấn phím Space: cổng nâng lên, chờ rồi đóng lại. Sau đó nhấn Kiểm tra.

Tự làm thử

using System.Collections;
using UnityEngine;

public class Portcullis : MonoBehaviour
{
    public float speed = 1.5f;
    public float height = 3f;
    Vector3 down;

    void Start()
    {
        down = transform.position;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Ride());
        }
    }

    IEnumerator Ride()
    {
        // Nâng lên height đơn vị với tốc độ speed và ghi log Open, giữ nguyên 1 giây, rồi hạ xuống và ghi log Closed
        yield return null;
    }
}

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

Tự luyện tập: Playground Unity