Menu
CoddyTech

Récompenses

Leçon 10 sur 18 du cours Jeu Unity : défense de tours de Coddy.

Chaque ennemi qu’une tour élimine rapporte sa reward. L’Enemy signale l’élimination comme il signale l’arrivée à la base, au moyen d’un événement statique, Killed, et le GameManager écoute cet événement et ajoute l’argent.

Une élimination ne doit être récompensée qu’une seule fois. Destroy ne supprime pas un objet immédiatement : cela se produit à la fin de la frame, et jusque-là, l’objet est toujours dans le jeu. Deux tirs peuvent toucher pendant la même frame, et le second trouve un ennemi à 0 point de vie qui est toujours présent. Si TakeDamage signale une élimination chaque fois que la santé est à 0 ou moins, ce second tir rapporte à nouveau une récompense. Un jeu de ballons avec des fléchettes présente le même piège, et un booléen permet de l’éviter :

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

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

L’ennemi n’a pas besoin d’un booléen supplémentaire, puisque sa santé indique déjà s’il est mort : un appel à TakeDamage qui trouve une santé à 0 ou moins n’a plus rien à faire.

challenge icon

Défi

Moyen
  1. Dans Enemy, déclare un événement statique public Killed (Action<Enemy>). Déclenche-le avec l’ennemi lorsque TakeDamage fait tomber sa santé à 0 ou moins, juste avant de le détruire.
  2. Une élimination ne rapporte qu’une seule fois : lorsque TakeDamage est appelé sur un ennemi dont la santé est déjà à 0 ou moins, il ne se passe rien.
  3. Dans GameManager, ajoute public void Earn(int amount), qui ajoute la somme à l’argent et l’affiche. Abonne-toi à Enemy.Killed à côté de ReachedBase et ajoute la reward de l’ennemi éliminé.

Appuie sur Play et regarde l’argent augmenter pendant que les tours fonctionnent, puis clique sur Check.

Essayez vous-même

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 iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Jeu Unity : défense de tours