MissingReferenceException: The object has been destroyed but you are still trying to access it
MissingReferenceException: The object of type 'X' has been destroyed but you are still trying to access it.
The object was destroyed, but your script kept a reference and used it afterwards. Unity objects can be destroyed while C# still holds the reference, so the variable is not null in the C# sense, but the object behind it is gone.
Read the Console line first
The message names the type that was destroyed, and the stack trace below it names the script and line that still used it.
Common causes
A list still holds destroyed enemies or pickups
You add spawned objects to a list and Destroy them later, but never remove them from the list. The next loop over the list hits a destroyed entry.
An event or coroutine outlives its object
A script subscribes to an event, or starts a coroutine on another object, and that object is destroyed. The callback runs and touches it.
A scene load destroyed what a persistent object points at
An object marked DontDestroyOnLoad keeps references to objects from the previous scene, which were destroyed when the new scene loaded.
The fix
// Unity overloads == so a destroyed object compares equal to null
enemies.RemoveAll(e => e == null);
foreach (var enemy in enemies)
{
if (enemy == null) continue;
enemy.TakeDamage(10);
}Stop it coming back
Remove objects from lists in the same place you destroy them, unsubscribe from events in OnDisable or OnDestroy, and use == null rather than ?. on Unity objects, because the null-conditional operator does not see destroyed objects as null. For bullets and effects, an object pool avoids the destroy-and-reference cycle entirely.
Questions
- How is this different from NullReferenceException?
- NullReferenceException means the reference was never set. MissingReferenceException means it pointed at a real object that has since been destroyed. The fix is different: assign the reference in the first case, stop using it after Destroy in the second.
- My code checks for null first. Why does it still throw?
- Unity treats a destroyed object as null only through its own
==operator on UnityEngine.Object. If the variable is typed as an interface orobject, or you test it withis null,?.or??, plain C# rules apply and the destroyed object looks alive. Store it as the component type, or cast to UnityEngine.Object before comparing. - It only happens after loading a new scene. Why?
- An object kept with DontDestroyOnLoad still holds references to objects from the previous scene, which were destroyed by the load. Clear or re-find those references when the new scene arrives, for example in a
SceneManager.sceneLoadedcallback.
Scripts that avoid it
Related errors
Got a different error? Paste it into the error lookup.