Menu
CoddyTech

Nagrody

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

Każdy wróg pokonany przez wieżę zapewnia nagrodę w postaci reward. Enemy zgłasza zabicie tak samo jak dotarcie do bazy: za pomocą zdarzenia statycznego Killed, a GameManager nasłuchuje go i dodaje pieniądze.

Zabicie musi być nagradzane tylko raz. Destroy nie usuwa obiektu od razu: następuje to na końcu klatki, a do tego czasu obiekt nadal jest w grze. Dwa strzały mogą trafić w tej samej klatce, a drugi trafia wroga z 0 punktów zdrowia, który nadal tam jest. Jeśli TakeDamage zgłasza zabicie za każdym razem, gdy zdrowie wynosi 0 lub mniej, drugi strzał przyznaje nagrodę ponownie. Gra w balony z lotkami ma tę samą pułapkę, którą można wyeliminować za pomocą bool:

public void Pop()
{
    if (popped)
    {
        return;
    }

    popped = true;
    Popped?.Invoke(this);
    Destroy(gameObject);
}

Wróg nie potrzebuje dodatkowego bool, ponieważ jego zdrowie już wskazuje, czy jest martwy: TakeDamage, które stwierdza, że zdrowie wynosi 0 lub mniej, nie ma już nic do zrobienia.

challenge icon

Wyzwanie

Średni
  1. W Enemy zadeklaruj publiczne statyczne zdarzenie Killed (Action<Enemy>). Wywołaj je, przekazując wroga, gdy TakeDamage zmniejszy jego zdrowie do 0 lub poniżej, tuż przed jego zniszczeniem.
  2. Za zabicie przyznawana jest nagroda tylko raz: gdy TakeDamage zostanie wywołane dla wroga, którego zdrowie wynosi już 0 lub mniej, nic się nie dzieje.
  3. W GameManager dodaj public void Earn(int amount), które zwiększa ilość pieniędzy i wyświetla ją. Zasubskrybuj Enemy.Killed obok ReachedBase i przyznaj nagrodę za zabitego wroga w postaci jego reward.

Naciśnij Graj i obserwuj, jak ilość pieniędzy rośnie, gdy wieże działają, a następnie naciśnij Sprawdź.

Spróbuj swoich sił

using System;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour, IDamageable
{
    public static readonly List<Enemy> All = new List<Enemy>();
    public static event Action<Enemy> ReachedBase;

    public EnemyData data;
    public Transform[] waypoints;

    private int next = 1;
    private int health;

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

    void OnEnable()
    {
        All.Add(this);
    }

    void OnDisable()
    {
        All.Remove(this);
    }

    void Update()
    {
        Vector3 target = waypoints[next].position;
        transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
        if (transform.position == target)
        {
            next++;
            if (next == waypoints.Length)
            {
                ReachedBase?.Invoke(this);
                Destroy(gameObject);
            }
        }
    }

    public void TakeDamage(int amount)
    {
        health -= amount;
        if (health <= 0)
        {
            Destroy(gameObject);
        }
    }
}
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