Uso de Don'tDestroyOnLoad en Unity para Gestión de Objetos Persistentes

Clase 17 de 60Curso Avanzado de Creación de RPGs con Unity

Resumen

Evita duplicar objetos entre escenas en Unity con un patrón sencillo y robusto: un solo player y una sola cámara persistentes, controlados por una variable estática y el método Don't Destroy On Load. Con este enfoque, mejoras el rendimiento y evitas inconsistencias al cambiar configuraciones entre escenas.

¿Por qué usar objetos persistentes entre escenas en Unity?

Mantener un único player y una única cámara evita conflictos cuando hay varias escenas con copias del mismo objeto. Si cambias el player o la configuración de la cámara en una escena, las otras no heredan esos cambios. Con Don't Destroy On Load, ambos se conservan al cargar nuevas escenas y se evita crear instancias infinitas.

  • Un solo estado global del player y la cámara ahorra recursos.
  • Coherencia visual: la configuración de la cámara se mantiene.
  • Evita duplicados con una bandera estática que controla la primera carga.
  • Base para HUD y más: el heads up display puede seguir la misma regla.

¿Cómo implementar un único player y cámara persistentes?

La clave es una variable estática en el player controller que indica si el player ya fue creado. Si no existe, se marca como creado y se aplica Don't Destroy On Load. Si ya existe, se destruye cualquier duplicado.

¿Cómo se declara y usa la variable estática?

  • Crea una booleana pública y estática: indica si el player fue creado.
  • En Start, comprueba su estado: si es la primera vez, persiste el objeto; si no, destruye el duplicado.
public class PlayerController : MonoBehaviour
{
    public static bool playerCreated; // por defecto: false

    void Start()
    {
        if (!playerCreated)
        {
            playerCreated = true;                  // marcar primera carga
            DontDestroyOnLoad(this.transform.gameObject); // persistir entre escenas
            // cargar animator y rigid body si aplica.
        }
        else
        {
            Destroy(gameObject); // evitar un segundo "conejito" en escena.
        }
    }
}

¿Dónde aplicar Don't Destroy On Load más allá del player?

Crea un script reutilizable para cualquier objeto que deba persistir: cámara, HUD u otros. Comprueba la bandera estática del player y actúa solo en la primera carga.

public class DontDestroyOnLoad : MonoBehaviour
{
    void Start()
    {
        if (!PlayerController.playerCreated)
        {
            DontDestroyOnLoad(this.transform.gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
}
  • Asigna este script al prefab de la Main Camera para evitar conflictos de instancia.
  • Elimina Update en este script: solo actúa al cargar.
  • En ejecución, verás una sección especial llamada Don't Destroy On Load donde aparecen el player y la cámara persistentes.

¿Qué ocurre con el teletransporte y el spawn entre escenas?

Al resolver la persistencia, el reto pasa a la sincronización: cuando cambias de escena, el player puede aparecer en una zona distinta a la esperada. La solución será relacionar cada punto de teletransporte con su punto de spawn correspondiente.

  • Define puntos de entrada y salida por escena.
  • Sincroniza el spawn del player con el portal o puerta usada.
  • Mantén la persistencia del player y la cámara, y solo actualiza su posición.

Esta base con Don't Destroy On Load te permite evitar cargas dinámicas infinitas de players y cámaras, y preparar el terreno para gestionar inventarios u objetos que no deban reiniciarse en cada escena.

¿Quieres que profundicemos en la lógica de teletransporte y emparejar puntos de spawn entre escenas? Cuéntame tu caso en los comentarios.