Autoloads frente a nodos corrientes

Godot ofrece una característica para cargar nodos automáticamente en la raíz de tu proyecto, permitiéndote acceder a ellos globalmente, que puede cumplir el rol de un Singleton: Singletons (AutoLoad). Estos nodos auto-cargados no se liberan cuando cambias la escena desde código con SceneTree.change_scene.

En esta guía aprenderás cuándo usar la función Autoload, y técnicas que puedes usar para evitarlo.

El problema del audio con cortes

Otros motores pueden fomentar la creación clases gestoras, singletons que organizan mucha funcionalidad en un objeto accesible globalmente. Godot ofrece varias maneras de evitar un estado global gracias al árbol de nodos y las señales.

Por ejemplo, digamos que estamos construyendo un juego de plataformas y queremos recoger monedas que reproducen un efecto de sonido. Hay uno nodo para ello: el AudioStreamPlayer. Pero si llamamos al AudioStreamPlayer mientras ya está reproduciendo un sonido, el nuevo sonido interrumpe al primero.

Un solución es codificar una clase gestora global, auto-cargada. Ésta genera un "pool" de nodos AudioStreamPlayer que recorre a medida que llega cada nueva petición de efectos de sonido. Digamos que llamamos esa clase Sound, puedes usarla desde cualquier sitio en tu proyecto llamando a Sound.play("coin_pickup.ogg"). Esto soluciona el problema a corto plazo, pero causa más problemas:

  1. Estado global: Un objeto es ahora responsable de todos los datos de los objetos. Si la clase Sound tiene errores o no tiene un AudioStreamPlayer disponible, todos los nodos que la llaman pueden fallar.
  2. Acceso global: Ahora cualquier objeto puede llamar a Sound.play(sound_path) desde cualquier sitio, ya no hay una forma fácil de encontrar la fuente de un error.
  3. Asignación de recursos global: Con un "pool" de nodos AudioStreamPlayer almacenado desde el principio, puedes tener muy pocos y enfrentarte a errores, o tener demasiados y usar más memoria de la necesaria.

Nota

Acerca del acceso global, el problema es que cualquier código en cualquier sitio podría pasar datos incorrectos al autoload Sound en nuestro ejemplo. Como resultado, el dominio a explorar para arreglar el error abarca todo el proyecto.

Cuando mantienes el código dentro de una escena, solo uno o dos scripts pueden estar involucrados en audio.

Compara esto con cada escena manteniendo tantos nodos AudioStreamPlayer como necesita dentro de sí y todos estos problemas desaparecen:

  1. Cada escena gestiona su propia información de estado. Si hay un problema con los datos, únicamente causará problemas en esa escena.
  2. Cada escena accede solo a sus propios nodos. Ahora, si hay un error, es fácil encontrar qué nodo es el culpable.
  3. Cada escena asigna exactamente la cantidad de recursos que necesita.

Gestionando funcionalidad o datos compartidos

Otra razón para usar un Autoload puede ser que quieras reutilizar el mismo método o dato en varias escenas.

En el caso de funciones, puedes crear un nuevo tipo de Node que proporcione esa característica para una escena individual usando la palabra clave class_name en GDScript.

Cuando se trata de datos, puedes:

  1. Crear un nuevo tipo de Resource para compartir los datos.
  2. Almacenar los datos en un objeto al que cada nodo tiene acceso. Por ejemplo, usado la propiedad owner para acceder al nodo raíz de la escena.

Cuándo deberías usar un Autoload

Los nodos auto-cargados pueden simplificar tu código en algunos casos:

  • Datos estáticos: Si necesitas datos que son exclusivos de una clase, como una base de datos, entonces un autoload puede ser una buena herramienta. En Godot no hay ninguna API de scripting para crear o gestionar datos estáticos de otra manera.
  • Funciones estáticas: Creando una biblioteca de funciones que solo devuelven valores.
  • Sistemas con un amplio alcance: Si el singleton está gestionando su propia información sin invadir los datos de otros objetos, entonces es una manera estupenda de crear sistemas que manejen tareas de amplio alcance. Por ejemplo, un sistema de misiones o diálogos.

Hasta Godot 3.1, otro uso era sólo por conveniencia: En GDScript se genera una variable global para el nombre de los autoloads, permitiéndote llamarlos desde cualquier archivo de script en tu proyecto. Pero en su lugar, ahora puedes usar la palabra clave class_name para conseguir autocompletado para un tipo en todo el proyecto.

Nota

Autoload no es exactamente un Singleton. Nada te impide instanciar copias de un nodo auto-cargado. Sólo es una herramienta que hace que un nodo se cargue automáticamente como un hijo de la raíz de tu árbol de escena, independientemente de la estructura de nodos de tu juego o de qué escenas ejecutes, p.ej. pulsando la tecla F6.

Como resultado, puedes acceder al nodo auto-cargado, por ejemplo un autoload llamado Sound, llamando a get_node("/root/Sound").