🎮 UnityDocs

Instantiate y Destroy: crear y eliminar objetos

Cómo crear GameObjects en tiempo de ejecución a partir de prefabs y cómo eliminarlos. Incluye las sobrecargas útiles, los errores típicos y por qué el pooling suele ser mejor que crear y destruir sin parar.

📄 ArtículoIntermedio✅ RevisadoUnity 6.0 LTSActualizado 2026-07-14
DificultadConceptual Código Matemáticas
Tiempo📖 Lectura 6 min · ⌨️ Práctica 15 min

Crear objetos: Instantiate#

Instantiate crea una copia de un prefab (o de cualquier objeto) en tiempo de ejecución. Es como pegar una instancia del prefab en la escena, pero desde código.

C#
using UnityEngine;

public class Cañon : MonoBehaviour
{
    [SerializeField] private GameObject balaPrefab;
    [SerializeField] private Transform punto;

    void Disparar()
    {
        // posición y rotación del cañón
        GameObject bala = Instantiate(balaPrefab, punto.position, punto.rotation);

        // Destruir la bala a los 3 segundos para no acumular basura
        Destroy(bala, 3f);
    }
}

Sobrecargas útiles#

C#
Instantiate(prefab);                          // en la posición del prefab
Instantiate(prefab, posicion, rotacion);      // en un sitio concreto
Instantiate(prefab, posicion, rotacion, padre); // como hijo de 'padre'
Instantiate(prefab, padre, false);            // como hijo, manteniendo pose local
Guarda el componente, no solo el GameObject

Instantiate devuelve el mismo tipo que le pasas. Si guardas una referencia tipada al prefab, obtienes el componente directamente sin GetComponent:

C#
[SerializeField] private Bala balaPrefab;   // tipo Bala, no GameObject
Bala bala = Instantiate(balaPrefab, pos, rot);
bala.Lanzar(direccion);   // acceso directo

Eliminar objetos: Destroy#

C#
Destroy(gameObject);       // destruye este objeto
Destroy(gameObject, 2f);   // lo destruye dentro de 2 segundos
Destroy(GetComponent<Rigidbody>());  // destruye solo un componente
Destroy no es inmediato

Destroy marca el objeto para eliminarlo al final del fotograma actual, no al instante. Durante el resto de ese frame el objeto sigue existiendo. Por eso, tras Destroy(x), si sigues usando x en el mismo frame, aún "funciona" pero está a punto de desaparecer. En el editor existe DestroyImmediate, pero no lo uses en juego: puede romper la iteración de la física.

El problema de crear y destruir sin parar#

Instanciar y destruir objetos constantemente (balas, partículas, enemigos que reaparecen) tiene dos costes: crear objetos genera basura para el recolector (GC), que provoca tirones; y destruir e instanciar de nuevo repite trabajo innecesario.

🧭 ¿Qué debería usar?
  • ¿Objeto que aparece una vez o rara vez? → Instantiate normal, sin más
  • ¿Objeto que aparece muchísimo (balas, impactos, enemigos)? → object pooling: crea un conjunto y recíclalos activando/desactivando en vez de crear/destruir

Unity 6 incluye ObjectPool<T> en UnityEngine.Pool para esto sin escribir el pool a mano.

Errores frecuentes#

  • Instanciar dentro de un bucle sin control y llenar la escena de objetos.
  • Olvidar destruir proyectiles que salen de pantalla (fugas que acaban con los FPS).
  • Usar el objeto justo después de Destroy esperando que ya no exista (aún vive ese frame).
  • Instanciar en Update cada fotograma sin querer (produce cientos de objetos por segundo).

Buenas prácticas#

  • Da a los objetos temporales una vida máxima (Destroy(obj, t)).
  • Para objetos frecuentes, usa pooling desde el principio.
  • Instancia como hijo de un contenedor vacío para mantener la Hierarchy ordenada.

Resumen#

Instantiate crea copias de prefabs en runtime y Destroy las elimina (al final del frame, no al instante). Para objetos que aparecen mucho, evita el ciclo crear/destruir y usa object pooling. Guarda referencias tipadas para saltarte el GetComponent.

Fuentes y para profundizar