Sự kiện điều khiển UI
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 15 trên 64.
Với sự kiện, HUD theo dõi trò chơi, còn trò chơi không biết gì về HUD. Health quản lý điểm máu và thông báo hai việc: máu đã thay đổi và máu đã về 0. Health không có trường nào dành cho thanh máu, văn bản hay màn hình kết thúc trò chơi, nên cùng một thành phần có thể dùng cho người chơi, kẻ địch không có HUD và cảnh kiểm thử:
public class Health : MonoBehaviour
{
public int maxHp = 100;
public event Action<int, int> OnChanged;
public event Action OnDied;
public int Hp { get; private set; }
void Awake()
{
Hp = maxHp;
}
public void TakeDamage(int amount)
{
if (Hp == 0) return;
Hp = Mathf.Max(Hp - amount, 0);
OnChanged?.Invoke(Hp, maxHp);
if (Hp == 0) OnDied?.Invoke();
}
}// HealthBar.cs, trên HUD
public Health health;
public Image bar;
void OnEnable() { health.OnChanged += Show; }
void OnDisable() { health.OnChanged -= Show; }
void Start()
{
Show(health.Hp, health.maxHp);
}
void Show(int hp, int max)
{
bar.fillAmount = (float)hp / max;
}Thanh máu chỉ lắng nghe khi đang hoạt động, thông qua cặp OnEnable và OnDisable. Sự kiện truyền cả hai con số, nên Show không cần lấy thêm thông tin nào từ Health. GameOverScreen đăng ký lắng nghe OnDied để hiển thị bảng điều khiển, còn âm thanh khi bị thương đăng ký lắng nghe OnChanged. Mỗi thành phần nằm trong script riêng, và Health không cần thay đổi vì chúng. Hp { get; private set; } cho phép HUD đọc lượng máu nhưng không thể thay đổi nó.
Sự kiện thông báo các thay đổi, vì vậy trước khi bị đánh lần đầu, thanh máu chưa nhận được thông báo nào. Thanh máu hiển thị lượng máu hiện tại một lần trong Start. Không hiển thị trong OnEnable: Unity gọi Awake rồi gọi OnEnable lần lượt cho từng đối tượng, nhưng không đảm bảo thứ tự. Vì vậy, OnEnable của thanh máu có thể chạy trước khi Awake của Health thiết lập Hp, khiến thanh máu hiển thị 0. Đến khi bất kỳ hàm Start nào chạy, tất cả hàm Awake đều đã chạy.
Thử thách
DễCho súng thông báo khi có thay đổi và để HUD lắng nghe.
- Trong
Gun.cs, thêmusing System;,public event Action<int, int> OnAmmoChangedvàpublic event Action<bool> OnReloading; kích hoạt chúng ở những chỗ có chú thích. - Trong
AmmoHud.cs, đăng ký trongOnEnable, hủy đăng ký trongOnDisable:ammoTexthiển thịAmmo: 4/6, cònreloadTextchỉ hiển thị khi đang nạp đạn. - Trong
Start, hiển thịgun.Ammovàgun.Reloadingmột lần.
Nhấn Chơi và bắn hết đạn hai lần. Sau đó nhấn Kiểm tra.
Tự làm thử
using UnityEngine;
using TMPro;
public class AmmoHud : MonoBehaviour
{
public Gun gun;
public TMP_Text ammoText;
public GameObject reloadText;
}
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ẩm2Giao 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