- Home /
Documentation unclear about destroying the object
I would like to see if this problem make sense to others than me.
I think that the documentation for Object.Destroy is wrong when saying:
Actual object destruction is always delayed until after the current Update loop (...)
I happen to call Destroy in OnCollisionEnter2D event and object gets destroyed before Update is called.
using UnityEngine;
public class TestCollision : MonoBehaviour
{
private bool destroy;
public void OnCollisionEnter2D(Collision2D coll)
{
Debug.Log(string.Format("{0} collided with {1}", name, coll.gameObject.name));
destroy = true;
Destroy(gameObject);
}
public void Update()
{
if (destroy)
{
//This does not get called, no Update after Destroy is called.
//Gets destroyed before Update
Debug.Log("Update gets called before destroying the object");
}
}
}
Shown in a diagram from Execution Order of Event Functions
Should this be considered for submitting for a false documentation statement?
Answer by meat5000 · Jan 27, 2015 at 12:22 PM
The references become unregistered but I'm sure the actual destruction happens next frame.
I have observed the effects of this using Overlap Sphere. I deleted a GameObject and within the same frame launched a sweep of Overlap Sphere, with which the Destroyed object was detected.
I had to use DestroyImmediate to remedy my problem.
Answer by sniper43 · Jan 27, 2015 at 01:01 PM
I think it means if you destroy INSIDE the Update() function the object will remain until Update() finishes.
An Update loop is current if it's being executed. Before that it's the next Update loop. Just because it's the same class does not mean it's the same loop.
You need to adapt your code so that this can't happen, beacuse influencing when what happens in seperate unreferenced sciprts is to my knowledge not possible.
Try:
using UnityEngine;
public class TestCollision : MonoBehaviour
{
private bool destroy;
public void OnCollisionEnter2D(Collision2D coll)
{
Debug.Log(string.Format("{0} collided with {1}", name, coll.gameObject.name));
destroy = true;
}
public void Update()
{
if (destroy)
{
Destroy(gameObject);
//This didn't get called because it wasn't inside of the current Update loop. It should still log.
Debug.Log("Update gets called before destroying the object");
}
}
}
And it should work.
Documentation should at least mention when it will be destroyed if used in OnCollisionEnter2D. This way it is unclear why this happens: if you have two object colliding and first destroys itself on collision, the second won't get even OnCollisionEnter event because the first object is already gone. I would presume that if collision happened, both will have the event raised, no mater what happens to the other one.
I imagine that all OnCollisionEnter, Update, etc. are delegate functions. It might work that after each delegate there is a check to see if anything was destroyed. But yes, the API should expand on that.