Récompenses
Leçon 13 sur 25 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.
Défi
MoyenChaque ennemi éliminé rapporte sa récompense.
- Dans
Enemy, ajoutepublic static event Action<Enemy> Killed;et déclenche cet événement dansTakeDamage, juste avant la destruction de l’ennemi. - Commence
TakeDamageparif (health <= 0) return;, pour qu’une élimination ne rapporte qu’une seule fois. - Dans
GameManager, ajoutepublic void Earn(int amount)(ajoute le montant et affiche-le), et abonne-toi àEnemy.Killedpour gagnerenemy.data.reward.
Appuie sur « Jouer » : l’argent augmente à mesure que les tours fonctionnent. Puis appuie sur « Vérifier ».
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);
}
}
}
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
Entraînez-vous par vous-même : Playground Unity