Nếu bạn đang suy nghĩ mà không cần viết, thì bạn chỉ nghĩ là bạn đang nghĩ. Linus Torvalds
STDIO Khi tiếp nhận và xử lý các sự kiện thu được, có những lúc chúng ta cần một khoảng thời gian chờ giữa việc nhận được sự kiện và xử lý sự kiện. Có khá nhiều những trường hợp cụ thể trong game mà cần delay lại trước khi thực hiện hành động. Tất cả những trường hợp đó, Unity đã hỗ trợ chúng ta hiện thực lại bằng các Coroutine. Vậy Coroutine là gì và sử dụng nó trong Unity ra sao, mời bạn đọc theo dõi bài viết.
Nội dung bài viết

Giới thiệu

Khi tiếp nhận và xử lý các sự kiện thu được, có những lúc chúng ta cần một khoảng thời gian chờ giữa việc nhận được sự kiện và xử lý sự kiện. Một ví dụ đơn giản mà tôi đã từng hiện thực lại trong bài viết Hiệu Ứng Camera Zoom Trong Unity. Khi cần một hiệu ứng zoom camera thật đẹp và mượt mà, tôi sử dụng kĩ thuật điều chỉnh size và nghỉ liên tục thành một vòng lặp. Độ chênh lệch kích thước camera và thời gian nghỉ là vừa đủ cho người dùng có trải nghiệm tốt nhất.

Ngoài ra còn khá nhiều những trường hợp cụ thể khác trong game mà cần delay lại trước khi thực hiện hành động. Tất cả những trường hợp đó, Unity đã hỗ trợ chúng ta hiện thực lại bằng các Coroutine. Vậy Coroutine là gì và sử dụng nó trong Unity ra sao, mời bạn đọc theo dõi bài viết.

Tiền đề bài viết

Bài viết thuộc Chương trình TỰ HỌC UNITY, sử dụng cho mục đích nghiên cứu cá nhân và training Unity.

Đối tượng hướng đến

Bài viết hướng đến đối tượng MỚI BẮT ĐẦU với Lập trình game trên Unity. Script hướng dẫn trong bài được viết bằng ngôn ngữ C# nên bạn đọc cần có kiến thức tương đối về C# để có thể đọc hiểu tốt.

Coroutine là gì

Khi bạn thực thi một hàm, hàm đó sẽ được xử lý hoàn toàn trước khi trả về một giá trị. Điều đó có nghĩa là dù hàm có phức tạp đến mấy cũng sẽ được xử lý trong duy nhất một vòng lặp của chương trình. Do đó, các hàm dạng này không thể được sử dụng để xử lý các hiệu ứng, animation hoặc các sự kiện diễn ra trong nhiều thời gian.

Coroutine là một thành phần của chương trình máy tính giúp chúng ta tạo ra các tiến trình con độc lập, bằng cách cho phép tại một vị trí có thể có nhiều entry point hoạt động trong cùng thời điểm. Trong Unity, Coroutine được sử dụng để bắt đầu một tiến trình độc lập với hàm Update và được gọi một lần duy nhất. Unity sẽ tự động quản lý tiến trình này cho đến khi nó kết thúc và được giải phóng.

Từ khoá yield

Từ khoá yield được ứng dụng nhiều trong các ngôn ngữ lập trình. yield là một tín hiệu để báo hiệu cho trình biên dịch biết đoạn code hay hàm chứa nó chính là một khối lặp, mặc dù không sử dụng các cú pháp thông thường đã biết. yield sẽ kết hợp với return, cho phép trả về các giá trị của khối lặp đó, đồng thời có thể quay trở lại khối lặp trong những lần lặp tiếp theo.

yield return sẽ không kết thúc phương thức chứa nó mà vẫn tiếp tục chạy cho đến khi thực thi xong lệnh cuối cùng của khối lặp. Muốn kết thúc phương thức, ta sử dụng yield break. Phương thức chứa yield có kiểu trả về là IEnumerator, được sử dụng nhằm tạo ra một Coroutine.

Mục đích của bài viết là giới thiệu và hướng dẫn một số ứng dụng thực tế của Coroutine trong Unity nên tôi không đề cập quá chi tiết về từ khoá yield. Bạn đọc có thể tham khảo link cuối bài viết hoặc liên lạc trực tiếp với tôi để hiểu rõ hơn về từ khoá yield.

WaitForSeconds

WaitForSeconds là một phương thức của Unity có chức năng trì hoãn một Coroutine với một khoảng thời gian tính bằng giây. WaitForSeconds được sử dụng duy nhất với từ khoá yield. Chi tiết về cách sử dụng các bạn xem ở các ví dụ thực tế ở phần dưới đây.

Sử dụng Coroutine trong Unity

Ta dùng phương thức StartCoroutine để bắt đầu một coroutine trong Unity. Nguyên mẫu của hàm như sau:

public Coroutine StartCoroutine(IEnumerator routine);

Tham số nhận vào là một IEnumerator, giá trị trả về của một hàm IEnumerator. Trong Unity, có thể có nhiều Coroutine hoạt động đồng thời trong cùng một thời gian. Ngoài ra, ta cũng có thể truyền trực tiếp tên hàm IEnumerator vào hàm dưới dạng chuỗi.

Ví dụ đơn giản dưới đây sẽ giúp các bạn hiểu được mục đích của việc sử dụng Coroutine và ứng dụng trong Unity:

void Start()
{
    Debug.Log("Starting " + Time.time);
    StartCoroutine(PrintfAfter(2.0f));
}

IEnumerator PrintfAfter(float seconds)
{
    yield return new WaitForSeconds(seconds);
    Debug.Log("Done " + Time.time);
}

Hàm PrintfAfter có kiểu trả về là IEnumerator. Dòng số 9, cặp từ khoá yield return, kết hợp với WaitForSeconds sẽ dừng hàm và bỏ qua dòng lệnh số 10 cho đến khi khoảng thời gian đã trôi qua hết. Khi đó dòng lệnh số 10 mới được thực thi và hàm sẽ thật sự kết thúc và được giải phóng.

Ngoài ứng dụng trong Hiệu Ứng Camera Zoom Trong Unity, tôi có sử dụng Coroutine trong một số trường hợp. Dưới đây là một số ví dụ thực tế mà tôi sử dụng trong các dự án cá nhân:

  • Disable đối tượng khi không còn sử dụng nữa. Đối tượng sẽ được đưa ra khỏi game và sẵn sàng được kích hoạt lại mà không cần khởi tạo mới:
void Update ()
{
    if (m_state == State.DEATH)
    {
        StartCoroutine(InactiveAfter(1f));
    }
}

IEnumerator InactiveAfter(float seconds)
{
    yield return new WaitForSeconds(seconds);

    GetComponent<Renderer>().enabled = false;
    GetComponent<Collider2D>().enabled = false;
    GetComponent<Rigidbody2D>().isKinematic = true;
}
  • Giải phóng đối tượng sau một khoảng thời gian:
void Update ()
{
    if (!GetComponent<Health>().m_isAlive)
        StartCoroutine(DestroyAfter(0.5f));
}

IEnumerator DestroyAfter(float seconds)
{
    yield return new WaitForSeconds(seconds);

    Score.m_score += 500;
    DoScoreEffect();
    Destroy(gameObject);
}

Tôi có sử dụng hiệu ứng và một số thao tác khác trước khi giải phóng đối tượng nên không thể sử dụng hàm Destroy với tham số thời gian delay. Coroutine là cách hiện thực đơn giản nhất trong trường hợp này.

Lời kết

Ngoài các ví dụ tôi nêu ở trên, còn rất nhiều trường hợp mà bạn có thể ứng dụng Coroutine vào project một cách hiệu quả. Hi vọng bài viết giúp được bạn có một giải pháp cho các vấn đề tương tự và ứng dụng tốt vào project cá nhân.

Tham khảo

https://en.wikipedia.org/wiki/Coroutine - 02/09/2015.

http://docs.unity3d.com/Manual/Coroutines.html - 02/09/2015.

Bạn cần hỗ trợ các dự án kết nối không dây?

Quí doanh nghiệp, cá nhân cần hỗ trợ, hợp tác các dự án IoT, kết nối không dây. Vui lòng liên hệ, hoặc gọi trực tiếp 0942.111912.

  • TỪ KHÓA
  • Arduino
  • ESP32
  • ESP8266
  • Wifi
  • Bluetooth
  • Zigbee
  • Raspberry Pi
THẢO LUẬN
ĐÓNG