- Home /
OnCollisionEnter performance
I have a 6x6x8 (about 288) stack of rigidbody cubes set up on my simple scene and i have a player controlled object that can either run into those cubes, making them topple or you can hit a key and explode causing the cubes to fly.
in the explosion loop in my player code, I paint the cubes red if they were directly in the blast radius and tell those specific cubes they have been hit. In the cube behavior script I have an OnCollisionEnter that checks if they have been hit by the explosion, and if they have, paint them green only if they hit the ground.
The code works fine but it gets really choppy for a few seconds during the initial blast. If i take out the block behavior code, it runs just fine. Im sure there is a more efficient way to do what im doing but I am not sure what it is. The code in question is below.
How can i do the OnCollisionEnter better?
My player code:
Vector3 explosionPos = myTransform.position;
Collider[] colliders = Physics.OverlapSphere(explosionPos, explosionRadius);
foreach(Collider hit in colliders)
{
if(!hit)
continue;
if(hit.rigidbody)
{
hit.rigidbody.AddExplosionForce(explosionPower, explosionPos, explosionRadius, 3.0f);
if(hit.collider.gameObject.tag == "Block"){
hit.GetComponent<BlockBehavior>().HasBeenHit(true);
}
hit.renderer.materials[0].color = Color.red;
}
}
My block behavior code snippet:
void OnCollisionEnter(Collision col){
if(hasBeenHit){
if(col.gameObject.name == "Ground"){
renderer.materials[0].color = Color.green;
}
}
}
public void CanCollect(bool col){
hasBeenHit = col;
}
So i did get it to run better by pulling the renderer.materials[0].color = Color.green; out of the collision method and putting it in the update, checking the hasBeenHit. I also cached the transform and use the cached one ins$$anonymous$$d. Not sure if this is still the proper way but its running better
maybe add a really small value yield in if(hit.rigidbody){ }
Answer by aldonaletto · Apr 10, 2012 at 02:55 AM
Your original code seemed efficient already.
But lots of collision events are reported before the block enters sleep mode, and they could be causing the slowdown. I think that making sure the color is set only once to green could improve the performance - in OnCollisionEnter or Update.
You could use two bool flags to do that:
bool isGreen = false; bool wasGreen = false;
void OnCollisionEnter(Collision col){ if (!isGreen && hasBeenHit && col.gameObject.name == "Ground"){ isGreen = true; } }
void Update(){ if (isGreen != wasGreen){ if (isGreen){ renderer.materials[0].color = Color.green; } wasGreen = isGreen; } }
Your answer
![](https://koobas.hobune.stream/wayback/20220613070118im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
What is causing this odd physics behaviour? 0 Answers
Change Inertia of rigidbody (Ixy) 1 Answer
How can you carry rigidbodies without them appearing jumpy? 1 Answer
Add Force without Rotation 2 Answers