Patrón Singleton: una instancia única en Unity

Clase 17 de 53Curso de C# para Videojuegos

Resumen

Aprende a implementar un Singleton en tu videojuego para mantener un único “jefe” que coordine estados sin conflictos. Con una variable static y una inicialización en awake, podrás asegurar que solo exista una instancia de tu GameManager, accesible desde cualquier script mediante su shared instance.

¿Qué es un singleton y por qué evita conflictos?

Un Singleton garantiza que solo haya una instancia de una clase en todo el juego. Si tuvieras dos managers, uno podría decir “pausa” y otro “en partida”: conflicto asegurado. Con un único GameManager, todos los sistemas obedecen la misma autoridad.

  • Una sola instancia compartida por todo el juego.
  • Evita estados contradictorios: menú, pausa, in game.
  • Acceso global y simple a variables comunes.

¿Cómo se declara con static?

La clave es usar una variable static del mismo tipo del script. Así representas la instancia única y compartida.

public static GameManager sharedInstance;
  • static: indica instancia única compartida.
  • sharedInstance: hace explícito que es la instancia compartida.

¿Qué ocurre al inicializar en awake?

El primer manager que “se despierte” en awake será el que gobierne. Si accidentalmente hay dos o más, solo el primero tomará el control.

void Awake()
{
    if (sharedInstance == null)
    {
        sharedInstance = this; // yo soy la instancia compartida
    }
}
  • Control seguro con if: evita reasignaciones.
  • El resto de copias quedan inactivas como managers.

¿Cómo se usa shared instance desde otros scripts?

Cualquier clase puede modificar el estado del juego accediendo a la sharedInstance del manager. Por ejemplo, desde un Player Controller, al detectar que el personaje toca el suelo en IsTouchingTheGround, actualizas el estado:

if (IsTouchingTheGround())
{
    GameManager.sharedInstance.currentGameState = gameState.ingame;
}
  • currentGameState público: accesible desde otros scripts sin problemas.
  • Comunicación directa y clara con el manager.

¿Cómo se prueba y qué casos prácticos cubre?

Puedes comprobar el cambio de estado al darle a play: por defecto estás en menú y, al tocar el suelo, pasas a ingame a través de la instancia compartida. Verás el cambio en pantalla y confirmarás que el Singleton funciona.

  • Flujo típico: menú → toca suelo → ingame.
  • Cambios orquestados por el GameManager único.

¿Qué beneficios aporta para comunicación entre clases?

Usar un Singleton permite notificar eventos importantes sin acoplar clases entre sí. El manager puede llevar el tracking de todo.

  • “He muerto”: el manager actualiza el estado y estadísticas.
  • “He tocado el suelo”: el manager avanza el juego.
  • “He ganado una moneda”: el manager suma y registra.

¿Cuándo usar singleton en player controller?

Si el juego es de un jugador, tiene sentido convertir el Player Controller en instancia compartida: una variable static y su asignación en awake.

  • Un solo jugador: un solo Player Controller compartido.
  • Misma lógica que en GameManager: static + awake + if.

¿Qué pasa si hay dos jugadores o más?

En un juego tipo “Mario y Luigi”, un Singleton para Player Controller no encaja: si mueves a Mario, podrías estar moviendo a Luigi también.

  • Dos jugadores: cada uno requiere su propia instancia.
  • Un singleton aquí puede mezclar controles y estados.
  • Reflexiona y elige diseño según número de jugadores.

¿Tú cómo lo implementarías en tu proyecto: Player Controller como singleton en single player y múltiple instancia en multijugador? Comparte tu razonamiento y resultados en los comentarios.

      Patrón Singleton: una instancia única en Unity