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 -=.
Défi
FacileLa base a besoin de vies, et un ennemi qui l’atteint doit lui en coûter.
- Dans
EnemyData, ajoute un int publicdamage: le nombre de vies que ce type retire à la base. - Dans
Enemy, déclare un événement statique publicReachedBasequi 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à. - Dans
GameManager, ajoute un int sérialiséstartLives(20) et un int privélivesqui commence à cette valeur. Abonne-toi àEnemy.ReachedBasedansOnEnableet désabonne-toi dansOnDisable. Chaque ennemi qui passe retire à la base le nombre de vies indiqué par son asset dansdamage. - Affiche les vies dans un TMP_Text sérialisé
livesText, sous la formeLives: 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++;
}
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.