Menu
CoddyTech

El Singleton

Parte de la sección Creación de juegos reales del Journey de Unity de Coddy. Lección 13 de 60.

Una referencia del Inspector necesita un objeto al que arrastrarla. Los enemigos que un generador crea durante el juego provienen de un prefab, y un prefab solo puede apuntar a recursos y a sus propias partes, nunca a un objeto de una escena, así que su campo GameManager está vacío. La solución habitual es un singleton: GameManager se guarda a sí mismo en un campo al que cualquier script puede acceder mediante el nombre de la clase.

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, en el prefab del enemigo
public void Die()
{
    GameManager.Instance.EnemyDown();
    Destroy(gameObject);
}

static significa que el campo pertenece a la clase, no a un objeto. Cada objeto GameManager tendría su propio kills, pero solo hay un Instance en todo el juego, y puedes acceder a él con el nombre de la clase: GameManager.Instance. Cualquier script puede leerlo, incluidos los enemigos creados hace un minuto, sin tener que rellenar un campo propio.

El administrador establece Instance = this; en Awake, donde this es el propio script. Unity ejecuta todos los Awake de la escena antes que cualquier Start, así que otros scripts pueden usar GameManager.Instance a partir de su Start. Un segundo GameManager en la escena sobrescribiría Instance con su propio valor; el capítulo Scenes and Levels muestra cómo evitarlo.

challenge icon

Desafío

Fácil

Haz que los meteoritos lleguen a GameManager mediante un singleton.

  1. En GameManager.cs, añade public static GameManager Instance; y un Awake() con Instance = this;.
  2. En Meteor.cs, elimina el campo game y llama a GameManager.Instance.MeteorLanded() y GameManager.Instance.MeteorCaught() en su lugar.

Pulsa «Jugar» y atrapa un meteorito: aparecerá Caught: 1, sin errores en la Consola. Después, pulsa «Comprobar».

Pruébalo tú mismo

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

Todas las lecciones de Creación de juegos reales

Practica por tu cuenta: Playground de Unity