Menu
CoddyTech

Le Singleton

Fait partie de la section Créer de vrais jeux du Journey Unity de Coddy. Leçon 13 sur 56.

Une référence dans l’Inspector a besoin d’un objet sur lequel faire glisser quelque chose. Les ennemis qu’un spawner crée pendant le jeu proviennent d’un prefab, et un prefab ne peut pointer que vers des assets et vers ses propres éléments, jamais vers un objet d’une scène ; leur champ GameManager est donc vide. La solution habituelle est un singleton : le GameManager se stocke lui-même dans un champ auquel chaque script peut accéder via le nom de la classe.

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;
    private int kills;

    void Awake()
    {
        Instance = this;
    }

    public void EnemyDown()
    {
        kills++;
        Debug.Log("Kills: " + kills);
    }
}
// Enemy.cs, sur le préfabriqué de l’ennemi
public void Die()
{
    GameManager.Instance.EnemyDown();
    Destroy(gameObject);
}

static signifie que le champ appartient à la classe, et non à un objet. Chaque objet GameManager aurait son propre kills, mais il n’y a qu’un seul Instance dans tout le jeu, auquel on accède avec le nom de la classe : GameManager.Instance. N’importe quel script peut le lire, y compris un ennemi apparu il y a une minute, sans avoir de champ à renseigner de son côté.

Le gestionnaire définit Instance = this; dans Awake, où this désigne le script lui-même. Unity exécute tous les Awake de la scène avant le moindre Start, donc les autres scripts peuvent utiliser GameManager.Instance dès leur Start. Un deuxième GameManager dans la scène remplacerait Instance par lui-même ; le chapitre Scenes and Levels montre comment l’éviter.

challenge icon

Défi

Facile

Des météores pleuvent. Le Spawner fait tomber un Meteor à partir d’un prefab toutes les 1.5 secondes, les flèches déplacent le Player, et le GameManager compte les météores attrapés avec MeteorCaught() et ceux qui touchent le sol avec MeteorLanded(). Ces scripts sont prêts.

Le script Meteor envoie ses rapports via son champ game, mais les météores proviennent d’un prefab : game est donc vide et chaque rapport échoue. Corrige ça avec un singleton :

  • Dans GameManager.cs, ajoute un champ public static Instance de type GameManager et définis-le sur ce script dans Awake.
  • Dans Meteor.cs, supprime le champ game et envoie les rapports via GameManager.Instance à la place.

Appuie sur Play, attrape quelques météores et laisse-en tomber quelques-uns, puis clique sur Check.

Essayez vous-même

using UnityEngine;
using TMPro;

public class GameManager : MonoBehaviour
{
    public TMP_Text caughtText;
    public TMP_Text shieldText;
    private int caught;
    private int shield = 3;

    public void MeteorCaught()
    {
        caught++;
        caughtText.text = "Caught: " + caught;
    }

    public void MeteorLanded()
    {
        shield--;
        shieldText.text = "Shield: " + shield;
    }
}
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 Créer de vrais jeux