Menu
CoddyTech

Ricompense

Lezione 13 di 25 del corso Gioco Unity: Tower Defense di Coddy.

Ogni nemico abbattuto da una torre paga la propria reward. L'Enemy segnala l'uccisione come segnala il raggiungimento della base, con un evento statico, Killed, e il GameManager ascolta e aggiunge il denaro.

Un'uccisione deve essere pagata una sola volta. Destroy non rimuove un oggetto immediatamente: l'operazione avviene alla fine del frame e, fino ad allora, l'oggetto è ancora in gioco. Due colpi possono andare a segno nello stesso frame e il secondo trova un nemico con 0 punti salute che è ancora lì. Se TakeDamage segnala un'uccisione ogni volta che la salute è pari o inferiore a 0, il secondo colpo paga di nuovo. Un gioco con palloncini e freccette presenta la stessa insidia, che si può evitare con un bool:

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

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

Il nemico non ha bisogno di un bool aggiuntivo, poiché la sua salute indica già se è morto: una chiamata a TakeDamage che trova la salute pari o inferiore a 0 non ha più nulla da fare.

challenge icon

Sfida

Medio

Ogni nemico ucciso fa guadagnare la sua ricompensa.

  1. In Enemy, aggiungi public static event Action<Enemy> Killed; e invocalo in TakeDamage subito prima che il nemico venga distrutto.
  2. Inizia TakeDamage con if (health <= 0) return;, così ogni uccisione viene ricompensata una sola volta.
  3. In GameManager, aggiungi public void Earn(int amount) (aggiungi l’importo e mostralo) e iscriviti a Enemy.Killed per guadagnare enemy.data.reward.

Premi «Gioca»: il denaro aumenta mentre le torri lavorano. Poi premi «Verifica».

Provalo tu

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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Gioco Unity: Tower Defense

Esercitati da solo: Playground Unity