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.
Thử thách
Trung bìnhĐợi mỗi đợt cho đến khi đấu trường không còn kẻ địch.
- Trong
Enemy, thêmpublic static event Action<Enemy> Died;và gọiDied?.Invoke(this);ngay trướcDestroy(gameObject);. - Trong
WaveSpawner, theo dõi số lượngalive: 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ớiEnemy.DiedvàOnDisablehủy đăng ký. - 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
1Thành phần, không phải hệ thống phân cấp
Thành phần nhỏTập lệnh kẻ địch cơ sởThành phần trừu tượngCác thành phần phối hợp với nhauÔn tập: tháp pháo mô-đunÔn tập: pháo nòng đôi4Dữ liệu tuần tự hóa
Lớp có thể tuần tự hóaDanh sách trong InspectorKiểu liệt kê trong InspectorÔn tập: Bảng vật phẩm rơiÔn tập: Quay vật phẩm7Máy trạng thái
Trạng thái dưới dạng lớpTrạng thái cảnh báoMáy trạng tháiChuyển trạng tháiTrí tuệ của kẻ địchHiệp sĩ tấn côngÔn tập: trạng thái cửa10Dự án: Đấu trường sinh tồn
Anh hùngCác loại kẻ địch2Giao diện trong Unity
IDamageableGiao diện và TryGetComponentGetComponentsÔn tập: phím tương tácÔn tập: đối tượng gần nhất trong tầm với5ScriptableObjects
Tài sản dữ liệuChỉ số vũ khíCài đặt dùng chungLưu gióSóng dưới dạng dữ liệuÔn tập: Cơ sở dữ liệu vật phẩmÔn tập: Mua hàng từ cửa hàng8Code có thể tái sử dụng
Phương thức mở rộngSingleton tổng quátCác hàm hỗ trợ tổng quátÔn tập: FindNearest3Sự kiện
Sự kiện C# trong UnityĐăng ký trong OnEnableCác trường UnityEventSự kiện điều khiển UIÔn tập: Cửa sổ bật lên thành tíchÔn tập: Bộ hẹn giờ cửa sổ bật lên6Lưu dữ liệu bằng JSON
JsonUtilityLưu trò chơiTải dữ liệu và giá trị mặc địnhÔn tập: các ô lưuChọn và xóa một ô lưu9Tái sử dụng đối tượng bằng pool
Vì sao cần pool đối tượngPool dùng hàng đợiObjectPool của UnityÔn tập: pool đạnTự luyện tập: Playground Unity