OnCollisionEnter and calling other functions

In my OnCollisionEnter (in which I destroy all objects colliding), I also call another function :

function OnCollisionEnter(collision : Collision) {
var controller;

	if (collision==null)
	{
		return;
	}
	
	if (gameObject==null || collision.gameObject==null || aCollision==true)
	{
		return;
	}
	
	aCollision=true;
	
	Debug.Log("aCollision = "+aCollision);
	Destroy(this);
	Destroy(gameObject);
	Destroy(collision.gameObject);
	
	controller = FindObjectOfType(Player); 
	if (controller) 
	{
		Debug.Log("Calling enemyDestroyed",this);
		yield controller.StartCoroutine("enemyDestroyed"); 
	}
}

However, I find that enemyDestroyed() is being repeatedly being called from the collision function, even though nothing should exist (or collide), and aCollide = true.

How can I stop enemyDestroyed() being repeatedly called ? OnCollisionStay does the same thing too.

Just a guess since I am not at home infront of my computer:

Destroy(this);
Should be done last.
Destroy(collision.gameObject);
Should destroy the object that collided with the object.

Now, I don’t know how Unity handles garbage collection or object dispose, but if you destroy the object executing the script (that the script lives in), I would imagine that no other code after it is destroyed gets executed.

So move Destroy(this) to the last line of the script and see what happens.

edit:
Might be the same with
Destroy(gameObject);
You shouldn’t have to call both ‘this’ and ‘gameObject’

No, its still being called, unfortunately.

Something is wrong then with the collision state.
I mean the logic is, object (a) ‘enters’ object (b)
At this point you have an onCollisionEnter trigger of object (b) since object (a) entered it.

Object (b)'s collider sould be of object (a), so when you Destroy(collision.gameObject), that “should” destroy object (a) regardless of the rest of your code.

If someone else doesn’t come up with an answer for you by the time I get back to my iMac, I’ll post some of my collision code to compare with what you are doing. My mind state right now is in .Net on a different project.

Nope, objects aren’t destroyed until the beginning of the next frame. (Unless you use DestroyImmediate, but generally you should stay away from that unless you really need it…so far I’ve used it once…) So any code after “Destroy(gameObject)” will still be executed.

There seems to be some unnecessary stuff there…I’m not sure what “var controller;” is doing, and I don’t think any of the “null” tests could ever be true, so you can get rid of them. (i.e., if OnCollisionEnter is called, “collision” can’t possibly be null, or else you would never have gotten a collision event in the first place.)

–Eric

They are there just to make sure all the checks will be valid, just in case the multiple collisions were passing invalid values.

But even with those gone, there is still continual collision detection.

I think the only way around it would be to use DestroyImmediate - which seems to work fine.

So, any idea why destroyed objects were still generated collisions ?

I believe you can get multiple collision notifications per frame. Since objects aren’t actually destroyed until the start of the next frame, that might explain what you’re seeing.

Is there a way to check if an object is pending destruction?

An easy way is to add a flag to your controller script that enemyDestroyed() sets when it is called the first time. enemyDestroyed() can check that flag first thin when called and exit if it has already been set instead of performing the rest of the function.

On the OnCollisionEnter() being called multiple times, I have seen similar behavior. First, I assume that script is on only one of the colliding objects. Second, it looks like you will call the enemyDestroyed() when you collide with any collider, not just the “enemy”, including the ground if it has a collider. Of course, in your case it looks like that should not continue very long since the script destroys everything :slight_smile: I have gotten multiple calls to OnCollisionEnter() on the same object when I am somehow “skimming” along the edge of the object and also when the object I am colliding against is itself colliding with another object. Sort of like a bouncing between objects.