Menu
CoddyTech

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.

challenge icon

Thử thách

Dễ

Cho súng thông báo khi có thay đổi và để HUD lắng nghe.

  1. Trong Gun.cs, thêm using System;, public event Action<int, int> OnAmmoChanged và public event Action<bool> OnReloading; kích hoạt chúng ở những chỗ có chú thích.
  2. Trong AmmoHud.cs, đăng ký trong OnEnable, hủy đăng ký trong OnDisable: ammoText hiển thị Ammo: 4/6, còn reloadText chỉ hiển thị khi đang nạp đạn.
  3. Trong Start, hiển thị gun.Ammo và gun.Reloading mộ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

Tự luyện tập: Playground Unity