🎮 UnityDocs

MissingReferenceException: el objeto fue destruido

Por qué ocurre este error (accedes a un objeto de Unity que ya destruiste), en qué se diferencia del NullReferenceException, cómo localizarlo y cómo prevenirlo.

🐛 ErrorIntermedio✅ RevisadoUnity 6.0 LTSActualizado 2026-07-15
DificultadConceptual Código Matemáticas
Tiempo📖 Lectura 5 min

El mensaje#

texto
MissingReferenceException: The object of type 'GameObject' has been destroyed
but you are still trying to access it.
  Torreta.Disparar () (at Assets/Scripts/Torreta.cs:34)

Qué significa#

Estás usando un objeto de Unity (un GameObject o componente) que fue destruido con Destroy, pero tu script todavía guarda una referencia a él e intenta usarlo. El objeto "ya no está", pero tu variable sigue apuntando a su fantasma.

MissingReference vs NullReference#

Se confunden, pero son distintos:

⚖️ Comparativa · MissingReference vs NullReference
NullReferenceExceptionMissingReferenceException
CausaLa variable nunca apuntó a nada (null)La variable apuntaba a algo que fue destruido
Ejemplo típicoReferencia del Inspector sin asignarGuardaste un objetivo y le hiciste Destroy
Pista"object reference not set""has been destroyed but you are still trying to access it"

Ver también NullReferenceException.

Ejemplo que lo provoca#

C#
public class Torreta : MonoBehaviour
{
    private GameObject objetivo;

    void FijarObjetivo(GameObject o) => objetivo = o;

    void Disparar()
    {
        // Si el objetivo murió (Destroy) y no lo hemos limpiado, esto peta
        transform.LookAt(objetivo.transform);   // MissingReferenceException
    }
}

El enemigo objetivo se destruyó, pero objetivo sigue "apuntando" a él.

Cómo prevenirlo#

1. Comprobar con == null (Unity lo entiende)#

Unity sobreescribe el operador == para que un objeto destruido se compare como null:

C#
void Disparar()
{
    if (objetivo == null) return;   // Unity detecta el objeto destruido
    transform.LookAt(objetivo.transform);
}
El null 'especial' de Unity

Aunque en C# la referencia técnicamente sigue existiendo, Unity hace que objetoDestruido == null devuelva true. Por eso if (objetivo == null) es la comprobación correcta. Ojo: el operador ?. usa el null puro de C#, así que objetivo?.Hacer() no detecta un objeto destruido de Unity. Con objetos de Unity, prefiere if (x == null) a x?..

2. Limpiar la referencia al destruir#

Cuando destruyas algo, avisa a quien lo usaba (con eventos) o pon la referencia a null.

3. Darse de baja de eventos#

Un caso clásico: un objeto destruido seguía suscrito a un evento. Desuscríbete siempre en OnDisable/OnDestroy (ver eventos).

Cómo localizarlo#

Igual que con NullReference: la última línea del error (Torreta.cs:34) te lleva a la línea exacta. Ahí hay una variable que apunta a un objeto ya destruido. Pregúntate: ¿qué destruí que todavía estoy usando?

Errores frecuentes#

  • Guardar una referencia a un enemigo/objeto y seguir usándola tras Destroy.
  • Usar ?. esperando que detecte objetos destruidos de Unity (no lo hace).
  • No darse de baja de eventos y que un objeto muerto siga "escuchando".
  • Corrutinas que siguen usando un objeto ya destruido.

Resumen#

MissingReferenceException = usas un objeto de Unity que ya destruiste. Se diferencia del NullReference en que aquí la referencia sí apuntó a algo, pero ese algo murió. Protégete con if (x == null) (que Unity entiende para objetos destruidos, a diferencia de ?.), limpia las referencias al destruir y date de baja de los eventos.

Fuentes y para profundizar