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.