- Home /
Check Which Collider Collided?
Hey guys,
I'm working in Unity2D in C#. I have a player character with a box collider 2D and circle collider 2D. I want to use an OnCollisionEnter that only triggers when the collision is with the circle collider, not the box collider.
I've done a fair bit of googling but couldn't find a source that explained how I could go about this (at least, not without making separate child objects for the collider which I'd much prefer not to do).
What I'm looking for would basically be something along the lines of:
private void OnCollisionStay2D(Collision2D collision)
{
if (theColliderThatCollided == theCircleCollider2D)
{
// Do Things
}
}
Answer by bpaynom · Sep 09, 2018 at 07:01 PM
private void OnCollisionEnter2D(Collision2D collision)
{
CircleCollider2D collider = collision.otherCollider as CircleCollider2D;
if ( collider != null )
{
// Do things
}
}
Just want to make sure my understanding here is correct:
It instantiates a new CircleCollider2D called collider and sets it equal to the other collider by converting the otherCollider to type CircleCollider2D. This works as long as otherCollider is correctly the CircleCollider2D, but if it's a box collider it returns null; therefor as long as the collider is the circle it does whatever, but if not it returns null and thus does nothing. Yes?
And this works on the player object as I understand it (which is what I'm looking for)?
Answer by Hellium · Sep 09, 2018 at 07:07 PM
Having two colliders on the same object is not advised. You should have one collider on your object, and another one attached to a child object.
You could do the following to check which collider triggered the OnCollisionStay2D event:
// Click and hold your mouse over the CircleCollider component and drop it to the `CircleCollider` field in the inspector
public Collider2D CircleCollider ;
// Click and hold your mouse over the BoxCollider component and drop it to the `CircleCollider` field in the inspector.
public Collider2D BoxCollider; // Not necessary in the end if you don't want to check against the box collider
private void OnCollisionStay2D(Collision2D collision)
{
if (collision.collider.GetInstanceID() == CircleCollider.GetInstanceID() )
{
// Do Things
}
}
Can you expand on why having two colliders on the same object isn't advisable? Is it just because it makes referencing them specifically more challenging, or...?
Well, I don't have any solid reasons except the one you are mentionning. But I often read that this practice is not advised.
https://answers.unity.com/questions/170610/multiple-triggers-on-one-object.html
I know that what you want to achieve is not possible with the plain OnCollisionEnter because you can't get the collider that sent the message.
Collision : https://docs.unity3d.com/ScriptReference/Collision.html
Collision2D : https://docs.unity3d.com/ScriptReference/Collision2D.html
On both Collision and Collision2D objects you can get the collider that sent the message. Just use collision.collider in both cases.
Answer by tormentoarmagedoom · Sep 09, 2018 at 06:11 PM
Good day.
Is much better to just check the distance friom the object (is lika a circle collider) with Vector3.Distance()
When the distance is < A Value -> do what you want and actiavate a bool variable (to know that has been activated and donta ctivate again)
Simple eh?!
Bye!
Thanks for the answer, that's an interesting solution. I am, however, a little concerned about the performance overhead there, presumably it's considerably higher?
Answer by lorenzofman2 · Sep 09, 2018 at 06:58 PM
I am not sure if this answers your question correctly since this function would go inside the other object (Not your player). This other object might call a function inside the player. I may be wrong but it appears that the object itself doesn't know which of its colliders have collided but the other object keeps a reference to it.
private void OnCollisionStay2D(Collision2D collision)
{
if (collision.collider as CircleCollider2D != null)
{
// Collided with a circle collider
}
if (collision.collider as BoxCollider2D != null)
{
// Collided with a box collider
}
}
From Microsoft C# Reference:
Or you might use the 'is' operator. Might be more readable: if (collision.collider is CircleCollider2D)The as operator (as) is like a cast operation. However, if the conversion isn't possible, as returns null instead of raising an exception
PS: I'm having a bad time with Unity Answers formatting. Can't modify the last line to be displayed as code
I had actually thought of something similar to this, but I'd really rather not have the other object (in this case, my terrain) have scripts on it.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
OnMouseDown with colliders behind the object being clicked 3 Answers
overlayCircle not working 1 Answer
How do I switch from Character player to Airship Vehicle using triggers? 0 Answers