Menu
CoddyTech

Dotrzyj do bazy

Lekcja 3 z 18 w kursie Gra Unity: Obrona wieżowa w Coddy.

Wróg, który dociera do ostatniego punktu nawigacyjnego, osiąga bazę: gracz traci życia, a wróg znika. Życia należą do GameManager, który wyświetla je na ekranie. Wróg nie powinien potrzebować odwołania do GameManager, żeby to zgłosić: wkrótce wrogowie będą tworzeni tuzinami z prefabrykatu, a prefabrykat nie może wskazywać obiektu znajdującego się w scenie.

Statyczne zdarzenie rozwiązuje oba problemy. Należy do klasy Enemy, a nie do pojedynczego wroga, więc GameManager subskrybuje je raz i otrzymuje powiadomienia od każdego wroga, także od tych utworzonych później. Każdy wróg wywołuje zdarzenie, przekazując siebie jako argument, dzięki czemu odbiorca może sprawdzić, jaki rodzaj wroga się przedostał. Moneta w grze platformowej zgłasza to w ten sam sposób:

public class Coin : MonoBehaviour
{
    public static event Action<Coin> Collected;
    public int value = 1;

    void OnTriggerEnter(Collider other)
    {
        Collected?.Invoke(this);
        Destroy(gameObject);
    }
}
// ScoreBoard.cs
void OnEnable()
{
    Coin.Collected += AddCoin;
}

void OnDisable()
{
    Coin.Collected -= AddCoin;
}

void AddCoin(Coin coin)
{
    score += coin.value;
}

Statyczne zdarzenie istnieje tak długo jak gra, więc -= jest ważniejsze niż kiedykolwiek: zniszczony ScoreBoard, który nie został odsubskrybowany, nadal otrzymywałby wywołania, a jego kod zakończyłby się błędem podczas dostępu do zniszczonego tekstu. OnEnable i OnDisable występują parami, więc każdemu += odpowiada -=.

challenge icon

Wyzwanie

Łatwy

Baza potrzebuje żyć, a wróg, który do niej dotrze, musi je odbierać.

  1. W EnemyData dodaj publiczne int damage: liczbę żyć odbieranych bazie przez ten rodzaj wroga.
  2. W Enemy zadeklaruj publiczne statyczne zdarzenie ReachedBase, które przekazuje wroga (Action<Enemy>). Gdy wróg dotrze do ostatniego punktu trasy, wywołaj to zdarzenie, przekazując samego siebie, i zniszcz wroga zamiast zatrzymywać go w tym miejscu.
  3. W GameManager dodaj serializowaną zmienną int startLives (20) oraz prywatną zmienną int lives, której początkowa wartość będzie taka sama. Zasubskrybuj zdarzenie Enemy.ReachedBase w OnEnable i anuluj subskrypcję w OnDisable. Każdy wróg, który się przedostanie, odejmuje od liczby żyć wartość damage ze swojego zasobu.
  4. Wyświetlaj liczbę żyć w serializowanym TMP_Text livesText jako Lives: 20 na początku i po każdej zmianie.

Obiekt Game ma komponent GameManager, w Inspectorze jest przypisany LivesText, a oba zasoby odbierają 1 życie. Naciśnij Play, poczekaj, aż obaj wrogowie dotrą do bazy, a następnie kliknij Check.

Spróbuj swoich sił

using UnityEngine;

public class Enemy : MonoBehaviour
{
    public EnemyData data;
    public Transform[] waypoints;

    private int next = 1;
    private int health;

    void Awake()
    {
        health = data.maxHealth;
    }

    void Update()
    {
        if (next >= waypoints.Length)
        {
            return;
        }

        Vector3 target = waypoints[next].position;
        transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
        if (transform.position == target)
        {
            next++;
        }
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Gra Unity: Obrona wieżowa