Menu
CoddyTech

Das Singleton

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

Eine Inspector-Referenz braucht etwas, worauf sie gezogen werden kann. Gegner, die ein Spawner während des Spiels erstellt, stammen aus einem Prefab, und ein Prefab kann nur auf Assets und seine eigenen Bestandteile verweisen, niemals auf ein Objekt in einer Szene. Daher ist ihr 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 einen eigenen Wert für 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 erst vor einer Minute erstellt 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 „Szenen und Level“ wird gezeigt, wie du das verhinderst.

challenge icon

Aufgabe

Einfach

Lass die Meteore den GameManager über ein Singleton erreichen.

  1. Füge in GameManager.cs public static GameManager Instance; und eine Awake()-Methode mit Instance = this; hinzu.
  2. Lösche in Meteor.cs das Feld game und rufe stattdessen GameManager.Instance.MeteorLanded() und GameManager.Instance.MeteorCaught() auf.

Drücke auf „Spielen“ und fange einen Meteor: Caught: 1 wird angezeigt, ohne dass Fehler in der Console auftreten. Klicke dann auf „Prüfen“.

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

Alle Lektionen in Echte Spiele entwickeln

Übe selbstständig: Unity-Playground