El Singleton
Parte de la sección Creación de juegos reales del Journey de Unity de Coddy. Lección 13 de 56.
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 todos los scripts pueden 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 desde su Start en adelante. Un segundo GameManager en la escena sobrescribiría Instance con su propio valor; el capítulo Scenes and Levels muestra cómo evitarlo.
Desafío
FácilCaen meteoritos. El Spawner suelta un Meteor de un prefab cada 1.5 segundos, las flechas mueven al Player y el GameManager cuenta los meteoritos atrapados con MeteorCaught() y los que golpean el suelo con MeteorLanded(). Esos scripts están listos.
El script Meteor informa a través de su campo game, pero los meteoritos provienen de un prefab, así que game está vacío y todos los informes fallan. Corrígelo con un singleton:
- En
GameManager.cs, agrega un campo público estáticoInstancede tipo GameManager y asígnale este script en Awake. - En
Meteor.cs, elimina el campogamee informa a través deGameManager.Instance.
Presiona Play, atrapa algunos meteoritos y deja que otros te alcancen; después, haz clic en Check.
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;
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Creación de juegos reales
1Texto en pantalla
Canvas y textoMuestra la puntuaciónDa formato a los númerosUn temporizador de cuenta regresivaRepaso: velocímetro4Escenas y niveles
Cargar una escenaReiniciar el nivelSiguiente nivelConservar entre escenasRepaso: selección de nivel10Proyecto: plataformas 3D
El recorridoPlataformas móviles2Botones y pantallas
Botones y onClickLambdasConectar en el InspectorPaneles activados y desactivadosBarras de saludRepaso: tienda de mejoras5Guardar con PlayerPrefs
Guardar un númeroCargar con un valor predeterminadoPuntuación más altaGuardar ajustesRepaso: monedas en el banco3El gestor del juego
Un solo script ejecuta el juegoEl SingletonEstados del juegoActivar el estadoRepaso: gestor de rondas6Proyecto: corredor infinito
Tres carrilesObstáculos por delante9El nuevo sistema de entrada
Dos sistemas de entradaTeclado y ratónPulsado en este fotogramaAcciones de entradaRepaso: cambio de entrada