Menu
CoddyTech

Atteindre la base

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

Un ennemi qui atteint le dernier point de passage est arrivé à la base : le joueur perd des vies et l’ennemi disparaît. Les vies appartiennent au GameManager, qui les affiche à l’écran. L’ennemi ne devrait pas avoir besoin d’une référence au GameManager pour le signaler : bientôt, les ennemis seront créés par dizaines à partir d’un prefab, et un prefab ne peut pas pointer vers un objet de la scène.

Un événement statique résout les deux problèmes. Il appartient à la classe Enemy, et non à un ennemi en particulier : le GameManager s’y abonne une seule fois et reçoit les notifications de tous les ennemis, y compris ceux créés plus tard. Chaque ennemi le déclenche en se passant lui-même en argument, afin que l’écouteur puisse savoir quel type d’ennemi est passé. Une pièce dans un jeu de plateforme fonctionne de la même manière :

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;
}

Un événement statique existe aussi longtemps que le jeu, donc le -= est plus important que jamais : un ScoreBoard détruit qui ne s’est jamais désabonné serait quand même appelé, et son code échouerait en essayant d’accéder à son texte détruit. OnEnable et OnDisable vont de pair : chaque += doit donc avoir son -=.

challenge icon

Défi

Facile

La base a besoin de vies, et un ennemi qui l’atteint doit lui en coûter.

  1. Dans EnemyData, ajoute un int public damage : le nombre de vies que ce type retire à la base.
  2. Dans Enemy, déclare un événement statique public ReachedBase qui transmet l’ennemi (Action<Enemy>). Quand l’ennemi arrive au dernier point de passage, déclenche l’événement en lui transmettant l’ennemi lui-même, puis détruis l’ennemi au lieu de le laisser s’arrêter là.
  3. Dans GameManager, ajoute un int sérialisé startLives (20) et un int privé lives qui commence à cette valeur. Abonne-toi à Enemy.ReachedBase dans OnEnable et désabonne-toi dans OnDisable. Chaque ennemi qui passe retire à la base le nombre de vies indiqué par son asset dans damage.
  4. Affiche les vies dans un TMP_Text sérialisé livesText, sous la forme Lives: 20, au démarrage et après chaque changement.

L’objet Game possède le GameManager, l’Inspector relie le LivesText, et les deux assets retirent chacun 1 vie. Appuie sur Play, attends que les deux ennemis atteignent la base, puis appuie sur Check.

Essayez vous-même

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