Search Unity

Checking if a specific collider is colliding

Discussion in 'Scripting' started by Rutenis, Apr 8, 2016.

Thread Status:
Not open for further replies.
  1. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    Hey, so today i came across this little problem. Cant figure out how to check if my CircleCollider2D is colliding.
    I've cant find any methods in this class that would work.

    Any ideas?

    -Thanks! :)
    -Cheers!
     
  2. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    This is what OnCollisionEnter2D() is for. There is also OnCollisionStay2D() and OnCollisionExit2D(). There are also trigger versions of all of these (e.g. OnTriggerEnter2D() ) as well as all of the 3D analogues (same names, but without '2D' at the end).

    These are called by messages. In a script attached to an object with a collider, define the collision function:

    Code (CSharp):
    1. void OnCollisionEnter2D(Collision2D col)
    2. {
    3.  
    4.     //Stuff that happens when the collider collides with something
    5.  
    6. }
    Everything within this case-sensitive function will be called when a collision between this object's collider and another happens.

    col in the example above is a Collision2D object that will contain a bunch of information about the collision including the object that was collided with; you can use this to only do certain things when specific colliders are collided with.

    A typical case is to filter by object tag. A script on an object with a collider might look like this:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Player : MonoBehaviour {
    5.     public float score;
    6.     public float health;
    7.  
    8.     void Update() {
    9.  
    10.     //Input, animation, whatever
    11.  
    12.     }
    13.  
    14.     void OnCollisionStay2D(Collision2D col) {
    15.  
    16.         if (col.gameObject.tag == "Enemy")
    17.             health -= 3;
    18.         if (col.gameObject.tag == "Coin")
    19.             score += 10;
    20.     }
    21. }
     
    Last edited: Apr 8, 2016
    supa4plex2 and essam191 like this.
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,528
    You can react via events, like Hyblademin points out.

    But if you want to do a quick poll of the collider, you have a few methods:
    Collider2D.IsTouchingLayers: tests if the collider touches anything on a specific layer mask... use all layers (-1) to test everything
    http://docs.unity3d.com/ScriptReference/Collider2D.IsTouchingLayers.html

    Collider2D.IsTouching: overlap test for 1 to 1 collider intersection
    http://docs.unity3d.com/ScriptReference/Collider2D.IsTouching.html

    And if there's a rigidbody, there are methods for IsTouchingLayers and IsTouching that tests all colliders associated with the Rigidbody2d:
    http://docs.unity3d.com/ScriptReference/Rigidbody2D.IsTouchingLayers.html
    http://docs.unity3d.com/ScriptReference/Rigidbody2D.IsTouching.html
     
  4. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    Yeah.. Not sure if i can still find the solution. I have a BoxCollider2D and a CircleCollider2D.

    I want to check them both seperataly.
     
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,528
    What do you mean you want to check them separately?

    Did none of the methods I share help?
     
  6. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    Yeah, sorry i feel dumb i just cant find it:D

    Basically i want to check if my circle collider is hitting a certain object but ignore box collider hitting it.
     
  7. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    You can selectively ignore collisions by only checking for certain kinds; in duct's post, isTouching() can check for a specific object, or isTouchingLayers() checks for a specific layer. In my post, there is a method to check for a specific tag. Any could work for you, I think, though isTouching() will require a reference to the collider you're checking for.

    Does your circle object have a Rigidbody2D?
     
    Lethn likes this.
  8. Rutenis

    Rutenis

    Joined:
    Aug 7, 2013
    Posts:
    297
    I'll just create a child object with a circle collider on it thats all and use it
     
    xXNoName2006Xx likes this.
  9. Ikno_

    Ikno_

    Joined:
    Jun 13, 2018
    Posts:
    2

    Thx, if(BoxCollider2D.isTouching(collision)) worked for me. You're a life saver.
     
  10. VLStudios

    VLStudios

    Joined:
    Jul 9, 2018
    Posts:
    2
    Hi, I know this is quite some later, but I noticed even now it is hard to find a stable and fast solution to this problem.
    So I thought I would still reply with my solution which seems to work well.
    Code (CSharp):
    1. public class "ClassNameHerë": MonoBehaviour
    2. {
    3.     public BoxCollider2D Collider1;
    4.     public CircleCollider2D Collider2;
    5.     public CircleCollider2D Collider3;
    6.  
    7. private void OnCollisionEnter2D(Collision2D other)
    8.     {
    9.              if(other.collider==Collider1)
    10.             {
    11.               Debug.Log("1");
    12.             }
    13.             if(other.collider==Collider2)
    14.             {
    15.                Debug.Log(2);
    16.             }
    17.             if(other.collider==Collider3)
    18.             {
    19.                Debug.Log(3)
    20.             }      
    21.         }
    22. }
    using this you will do a certain action when collided with a speciffic collider, even if they are on the same gameobject.


    However note that Collider does not have a id varialbe or something like that allows unity to detect the difference between the same type collider on the same gameobject. but as long as the colliders are from a different type it will work.
    if you want 2 of the same type of collider on a single object but still want to notice the difference you will most likely have to go to unity's class definition for that type collider and add a public int, float, long, or string ID which you can get in code to get which collider of a speciffic type you interact with.
     
  11. merrillbaker13

    merrillbaker13

    Joined:
    Jan 18, 2020
    Posts:
    1
    I understand what your trying to say, I have been having the same exact issue. When you use OnColliderEnter2D() or OnTriggerEnter2D you only have the option to specify the object you are colliding with not to specify which collider that is attached to the object that has the script attached to it. I have had the same issue and never could find a perfect solution, in fact if you create a child of the object with another collider and there is a script on the parent object that runs either the OnColliderEnter2D or OnTriggerEnter2D function then it will also be checking the collider of the child object as well and likely create bugs. What I tend to do is create a child like your talking about but add in a function in script attached to the parent to activate and deactivate the child so that its only active when in use but then you still run the risk of creating bugs that appear in that moment the child is active so sometimes its also necessary to run another function to enable and disable the collider on the parent accordingly as well. I know its a lot of extra work and isn't exactly a perfect solution but its the only solution i have come up with especially since when you search for a solution you generally are met with answers about using OnColliderEnter2D or OnTriggerEnter2D and specifying the collider with a tag or layer but the issue isn't with the collider your colliding with but specifying which collider is attached to the object that is running the script to start with. I hope this helps someone searching for similar answers in the future.
     
    VortexInCortex and TheLurkingDev like this.
  12. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    The OP's question is asking for a check that can be performed to see if they are colliding. The incorrect solutions are events, not a check.
    They are used in different places at different times.
     
  13. JDinnit

    JDinnit

    Joined:
    Apr 20, 2018
    Posts:
    1
    This is an old thread and my solution might not be perfect for OPs context by wanted to share in case anyone has a similar issue.

    I essentially just put the collider I want to check on a child gameobject, added a basic script to the object with an OnCollisionEnter, used CompareTag to check its not colliding with the player (itself) that set a public bool, then started a IEnumerator to make sure it only registered the collision once.

    I then hooked this up to the main script, checked in FixedUpdate (was adding force on collision)for the collision bool, set it to false and performed the code I wanted to fire on collision.

    I'm a beginner so there is probably more efficient ways of doing this but it seems to do what I need so far.
     
  14. bdeniz1997

    bdeniz1997

    Joined:
    Jan 26, 2021
    Posts:
    15
    for example lets say you have 2 classes called player and enemy
    player has one collider and enemy has 2 colliders. one being a box collider
    and the other is an edge collider.

    you go like this:

    //this is the player script.
    private void onCollisionEnter2D(Collision2D other){
    BoxCollider2D enemyBox = other.gameObject.GetComponent<BoxCollider2D>();
    EdgeCollider2D enemyEdge = other.gameObject.GetComponent<EdgeCollider2D>();

    if(other == enemyBox){
    // if its the box collider
    }else if(other==enemyEdge){
    // if its the edge collider
    }
    }


    you simply get the gameobject of other, and by get component function, you get the collider that is attached to it.
    you check for the box collider and the edge collider attached to the gameObject, that is being collided to our player.

    i dont know what is going to happen if you have more than 1 collider that is the same type, you probably gonna have to create an array and index them but idk if the index is going to change according to the collision. so anyone tries this out has to find it out themselves it if it works or not. but, having only 1 collider of each works.
     
    Seehundy1995 likes this.
  15. nickhoude21

    nickhoude21

    Joined:
    Jun 4, 2021
    Posts:
    1
    Hey, so yes I know this question is 5 years old, but I seem to have found a solution

    my class looks like this and I have four colliders in a sort of

    | |
    | o |
    | _ |

    shape, like a bucket.

    So what I did is I made the public CircleCollider2D; which is the o in this case, and I wanted to only do something if the circle collider is the one being collided with.

    In the Unity Editor Inspector, I passed the net object in as the public Rigidbody2D net, and the CircleCollider2D in as CircleCollider2D goal.

    Then as you can see, I made another Collider2D col object and set it to the Collider2D on the gameObject of what was colliding with the basket, then checked if the collision was between col (the object colliding with this class) and goal (the circle collider) and set up a debug.log to test it and this actually worked, much to my surprise

    public class Basket : MonoBehaviour
    {
    public Rigidbody2D net;
    public CircleCollider2D goal;
    // Start is called before the first frame update
    void Start()
    {

    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
    Collider2D col = collision.gameObject.GetComponent<Collider2D>();
    if (goal.IsTouching(col))
    {
    Debug.Log("Working");
    }
    }
    // Update is called once per frame
    void Update()
    {

    }
    }
     
  16. logicandchaos

    logicandchaos

    Joined:
    May 16, 2016
    Posts:
    26

    It sounds like you need to learn about collision layers, you can set up layers so collisions are ignored between certain objects. As for OPs original question I'm sure the supplied isTouching methods are exactly what they need but they are not sure how to code it in. IsTouching does exactly what the OP asked. If you are using child objects with collisions and you want the OnCollision methods to only fire for their colliders, simply put the script with the collision call on the child object, not the parent, then when there is a collision it can call whatever method from the parent object. It's all about how you set up your objects.
     
  17. randumzgaming

    randumzgaming

    Joined:
    Nov 27, 2022
    Posts:
    12
    Thank you SO much for this!!!!!!!!!!! It was the answer I was looking for in my own personal project.
     
Thread Status:
Not open for further replies.