- Home /
Destroying an object not working
I'm trying to destroy some objects as follows:
public void ClearAllEditableObjects() {
foreach (GameObject obj in GameObject.FindGameObjectsWithTag("EditableObject")) {
print ("ClearAllEditableObjects destroying object (id " +
obj.GetInstanceID() + ") with " +
((obj.rigidbody == null) ? " no rigidbody" : " a rigidbody"));
Destroy(obj);
print ("ClearAllEditableObjects testing object (id " +
obj.GetInstanceID() + ") null test yields " + (obj == null));
}
}
The text output is:
ClearAllEditableObjects destroying object (id 10262) with a rigidbody
ClearAllEditableObjects testing object (id 10262) null test yields False
My understanding is that Destroy(obj) will not destroy the object immediately, but will do so before the next frame; and that it will test as being equal to null until that happens. Any clue why this doesn't seem to happen here? Another script is trying to use the object later (it is being returned from a Physics.OverlapSphere() call), which then causes problems. Any thoughts gratefully received! Regards,
Andy
Answer by whydoidoit · Jan 25, 2013 at 12:10 AM
It starts returning null after it has been destroyed at the end of the frame, until then it appears valid. Use DestroyImmediate to delete immediately.
I considered that option, but the warnings in the documentation seemed to strongly suggest that was not the best idea: "This function should only be used when writing editor code since the delayed destruction will never be invoked in edit mode. In game code it is recommended to use Object.Destroy ins$$anonymous$$d. Destroy is always delayed (but executed within the same frame) Use this function with care since it can destroy assets permanently!". Is there no other way to tell if an object is scheduled for deletion?
In that case, simply clear the reference after the Destroy() manually:
obj=null;
But in the problematic code, it is not being accessed through the same reference; it is being returned by Physics.OverlapSphere().
Personally, I'd still use DestroyImmediate. A workaround could be to deactivate the object for the rest of the frame. So ins$$anonymous$$d of my suggestion above (which didn't make much sense anyway, since "obj" was a local variable), use
obj.SetActive(false);
The reason that they suggest that is that a variable with a valid reference in Update may be invalid by LateUpdate (or a coroutine etc) - I'd use DestroyImmediate.