Menu
CoddyTech

Dọn sạch đấu trường

Thuộc phần Kiến trúc trò chơi trong Unity trong hành trình Unity của Coddy. Bài học 55 trên 64.

Một sự kiện được đánh dấu static thuộc về lớp, không thuộc về một đối tượng cụ thể. Sẽ chỉ có một Enemy.Died cho tất cả kẻ địch từng tồn tại, vì vậy bộ tạo kẻ địch có thể đăng ký theo dõi sự kiện bằng Enemy.Died += OnEnemyDied; trước khi có kẻ địch nào tồn tại, và mỗi kẻ địch phát sự kiện đó với chính nó làm đối số. Ý tưởng tương tự trong C# thuần:

public class Coin
{
    public static event Action<Coin> Picked;

    public void Pick()
    {
        Picked?.Invoke(this);
    }
}

public class Purse
{
    private int coins;

    public Purse()
    {
        Coin.Picked += OnPicked;   // chưa cần Coin
    }

    void OnPicked(Coin coin)
    {
        coins++;
    }
}

Sự kiện của instance được truy cập thông qua một đối tượng, như hero.Died; sự kiện tĩnh được truy cập thông qua tên lớp, như Coin.Picked. Sự kiện tĩnh tồn tại lâu hơn mọi đối tượng, vì vậy hãy hủy đăng ký trong OnDisable, nếu không bộ tạo kẻ địch đã bị hủy vẫn nằm trong danh sách của sự kiện.

challenge icon

Thử thách

Trung bình

Đợi mỗi đợt cho đến khi đấu trường không còn kẻ địch.

  1. Trong Enemy, thêm public static event Action<Enemy> Died; và gọi Died?.Invoke(this); ngay trước Destroy(gameObject);.
  2. Trong WaveSpawner, theo dõi số lượng alive: tăng 1 sau mỗi lần sinh ra kẻ địch, giảm 1 trong một phương thức mà OnEnable đăng ký với Enemy.Died và OnDisable hủy đăng ký.
  3. Sau khi một đợt sinh ra kẻ địch, chờ trong khi alive > 0.

Nhấn Chơi và đánh bại đợt 1: đợt 2 xuất hiện sau 2 giây. Sau đó nhấn Kiểm tra.

Tự làm thử

using System.Collections;
using UnityEngine;

public class WaveSpawner : MonoBehaviour
{
    [SerializeField] private WaveSet waveSet;
    [SerializeField] private Transform[] spawnPoints;

    public int Wave { get; private set; }

    void Start()
    {
        StartCoroutine(RunWaves());
    }

    IEnumerator RunWaves()
    {
        while (true)
        {
            foreach (Wave wave in waveSet.waves)
            {
                Wave++;
                Debug.Log("Wave " + Wave);
                for (int i = 0; i < wave.count; i++)
                {
                    Transform point = spawnPoints[i % spawnPoints.Length];
                    Instantiate(wave.enemy, point.position, Quaternion.identity);
                    yield return new WaitForSeconds(wave.spacing);
                }
                yield return new WaitForSeconds(waveSet.restBetweenWaves);
            }
        }
    }
}

Tất cả bài học trong Kiến trúc trò chơi trong Unity

Tự luyện tập: Playground Unity