Menu
CoddyTech

Das Singleton

Teil des Abschnitts Echte Spiele entwickeln der Unity-Journey von Coddy. Lektion 13 von 56.

Eine Inspector-Referenz braucht ein Objekt, auf das du etwas ziehen kannst. Gegner, die ein Spawner während des Spiels erstellt, stammen aus einem Prefab, und ein Prefab kann nur auf Assets und auf seine eigenen Bestandteile verweisen, niemals auf ein Objekt in einer Szene. Deshalb ist sein GameManager-Feld leer. Die übliche Lösung ist ein Singleton: Der GameManager speichert sich selbst in einem Feld, auf das jedes Skript über den Klassennamen zugreifen kann.

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, auf dem Gegner-Prefab
public void Die()
{
    GameManager.Instance.EnemyDown();
    Destroy(gameObject);
}

static bedeutet, dass das Feld zur Klasse gehört, nicht zu einem Objekt. Jedes GameManager-Objekt hätte ein eigenes kills, aber im ganzen Spiel gibt es nur eine Instance, und du erreichst sie über den Klassennamen: GameManager.Instance. Jedes Skript kann darauf zugreifen, auch ein Gegner, der vor einer Minute gespawnt wurde, ohne dass ein eigenes Feld ausgefüllt werden muss.

Der Manager setzt Instance = this; in Awake, wobei this das Skript selbst ist. Unity führt jedes Awake in der Szene aus, bevor irgendein Start ausgeführt wird. Deshalb können andere Skripte ab ihrem Start GameManager.Instance verwenden. Ein zweiter GameManager in der Szene würde Instance mit sich selbst überschreiben; im Kapitel „Scenes and Levels“ wird gezeigt, wie du das verhinderst.

challenge icon

Aufgabe

Einfach

Meteore regnen herab. Der Spawner lässt alle 1.5 Sekunden einen Meteor aus einem Prefab fallen, die Pfeiltasten bewegen den Player und der GameManager zählt einen abgefangenen Meteor mit MeteorCaught() und einen Meteor, der den Boden trifft, mit MeteorLanded(). Diese Skripte sind bereit.

Das Meteor-Skript meldet Ereignisse über sein game-Feld, aber die Meteore stammen aus einem Prefab, daher ist game leer und jede Meldung schlägt fehl. Behebe das mit einem Singleton:

  • Füge in GameManager.cs ein öffentliches statisches Feld Instance vom Typ GameManager hinzu und setze es in Awake auf dieses Skript.
  • Lösche in Meteor.cs das Feld game und melde Ereignisse stattdessen über GameManager.Instance.

Drücke Play, fange ein paar Meteore ab und lass ein paar durch, dann Check.

Probier es selbst

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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Echte Spiele entwickeln