Ir al contenido

SingletonNode

SingletonNode es una clase base que garantiza una única instancia activa por script. Si otra instancia del mismo script entra al árbol de escenas, el duplicado se libera automáticamente.

Cubre dos patrones de uso:

  • Por escena — el nodo vive como hijo de una escena y se destruye cuando esa escena sale del árbol.
  • Root manual — el nodo se crea desde código, se monta en root y persiste entre cambios de escena.
  1. Descarga ss-gameforge-singleton desde la página de releases.
  2. Copia addons/ss-gameforge-singleton/ dentro de res://addons/ en tu proyecto.
  3. Activa ss-gameforge-singleton en Project Settings → Plugins.
MétodoDescripción
SingletonNode.get_instance_for(script)Devuelve la instancia activa para una clase script.
SingletonNode.ensure_for(script, root, name)Crea y añade la instancia si no existe.
is_active_instance()Devuelve true si este nodo es el singleton activo.

Usa esto cuando el singleton solo tiene sentido dentro de una escena específica y debe destruirse al salir: un director de combate de jefe, un controlador de puzle, un gestor de sesión de run.

Extiende SingletonNode y expón un acceso estático tipado:

extends SingletonNode
class_name BossFightDirector
static var i: BossFightDirector:
get:
return SingletonNode.get_instance_for(BossFightDirector) as BossFightDirector
var phase := 1
func next_phase() -> int:
phase += 1
return phase

Añade el nodo como hijo de la escena del combate del jefe. Si un duplicado entra al árbol se libera automáticamente.

# seguro desde cualquier lugar — devuelve null si no estamos en la escena del jefe
if BossFightDirector.i:
BossFightDirector.i.next_phase()

Usa esto cuando el singleton debe persistir entre cambios de escena pero quieres controlar exactamente cuándo se crea: un servicio de guardado que solo existe tras iniciar sesión, un servicio de red solo cuando hay conexión.

extends SingletonNode
class_name SaveService
static var i: SaveService:
get:
return SingletonNode.get_instance_for(SaveService) as SaveService
func save_game() -> void:
print("[SaveService] Guardando...")

Créalo desde código y móntalo en root:

func _ready() -> void:
SingletonNode.ensure_for(SaveService, get_tree().root, "SaveService")

El nodo ahora vive bajo root, sobrevive a change_scene_to_* y es accesible via SaveService.i desde cualquier lugar.