- Home /
Colliding with similar object
Hi,
I came up to this scenario which I think must be rather common. I have several similar objects (asteroids) floating in space. I want to draw some impact and play sound when they collide with each other.
They are instances of the same Prefab, so they have the same tag and the same Monobehaviour. When they collide, I get two collisions, not just one. One detected by the first, another by the second.
Is there a simple way to just discard the second call ?
For now, what I'm doing is this, but it's far from ideal :
void OnCollisionEnter2D (Collision2D collision)
{
if (collision.gameObject.tag == gameObject.tag)
collision.gameObject.GetComponent<CollidingObject>().StopCoroutine ("Collide");
StartCoroutine ("Collide", collision);
}
public IEnumerator Collide (Collision2D collision)
{
yield return new WaitForSeconds (0.001f);
// handle collision
}
Just an idea, but presumably there is potential for multiple collisions between more than just two objects within a very small interval, so wouldn't you want to prevent those other collisions' sounds too? How about activating a timer (duration of the sound) and allow another play only if the timer had reached zero?
You could count the time from a static float, then the first collision that found the time was up could launch a new play of the sound. Other collisions would see the time was not up and ignore
It makes sense yes, at least for the sound. I'm also concerned about the graphics, as I draw an impact at the point of contact, and when colliding two similar objects, I get two, which isn't so good performance wise, especially that I expect many collisions..
Answer by richyrich · Oct 19, 2014 at 01:51 PM
You could compare two GameObjects by their instance IDs, then only choose the ID with the lowest value. Personally, I've being something similar recently, but assigned IDs in a similar manner to the suggestion by DFLY. However, there is another potential issue. You also need to make sure you are not repeating the same collision... you can have more than one collision per frame between the same two colliders. http://docs.unity3d.com/Manual/ExecutionOrder.html
To avoid this issue, you could set a flag during FixedUpdate to prevent further collisions during that frame. You would then reset the flag during Update.
Good idea, thanks! This works perfectly.
if (collision.gameObject.tag != gameObject.tag || collision.gameObject.GetInstanceID() < gameObject.GetInstanceID())
// handle collision
If you could accept the answer, so others know the problem has been resolved, that would be cool. Glad it solved your problem
sorry, I have a new account, it took me to log with my former account to do it.. Thanks again.
Answer by DFLY · Oct 19, 2014 at 01:34 PM
What you can do is give each instance of the prefab a number one unit higher than the last prefab e.g.: "1 , 2 , 3 ...." Then use an if statement to make only the largest numbered prefab detect the collision. To number your prefabs to start with use something like:
function InstantiateBlock(){
blockNumber ++;
blockNumberToString = blockNumber.ToString();
newtBlock = Instantiate (tBlock, (transform.position + Vector3(0.0, 10.0, 0.0)), Quaternion.identity);
newtBlock.name = blockNumberToString;
blockName = newtBlock.name;
thisBlock = GameObject.Find(blockName);
thisBlock.rigidbody.velocity = Vector3 (0 , startVel , 0);
}
Your answer
Follow this Question
Related Questions
Rigidbody colliders 1 Answer
rigid bodies passing through one another. 1 Answer
ExplosionForce On Instantiated Object 1 Answer
onTriggerEnter Won't Work 1 Answer