Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Detect multiple collisions with the same collider?

Discussion in 'Scripting' started by Lars-Kristian, Jun 16, 2014.

Thread Status:
Not open for further replies.
  1. Lars-Kristian

    Lars-Kristian

    Joined:
    Jun 26, 2013
    Posts:
    64
    Does anybody know of a good way to detect multiple collisions with the same collider?

    In the illustration down below, I have a sphere that is colliding with a wall while moving upwards. I want to detect the 2nd collision when it hits the top. Problem is both walls is the same mesh collider.

    Illustration.png
     
  2. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
  3. Lars-Kristian

    Lars-Kristian

    Joined:
    Jun 26, 2013
    Posts:
    64
    Thanks.

    Will the physics engine generate new contact points for every update? Is it easy to track old contact points?
     
  4. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    i would start tracking distances between contact point and base on that see if it changed enough to determine if a contact is on a different axis ...
     
  5. Lars-Kristian

    Lars-Kristian

    Joined:
    Jun 26, 2013
    Posts:
    64
    Thanks for the help. I manage to solve this problem in the following way.

    A "CustomContactPoint" is created when a collision is detected (and given a color for debuging).
    On every OnCollisionStay the code checks if the contact point already exists. If it does, its information is updated.


    Demo - Walls.gif
    To check if two contact points are the same, the normal vector is used. If this fails the collision point position is used instead. This allows it to be tracked around corners.


    Demo - Corner.gif
    I cannot guarantee this code works for everyone. However, it will be a nice starting point.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3.  
    4. public class WallCollisionDetection : MonoBehaviour {
    5.  
    6.     public bool debug = true;
    7.  
    8.     private List<CustomContactPoint> wallcontatcs = new List<CustomContactPoint>();
    9.  
    10.     void FixedUpdate()
    11.     {
    12.  
    13.         for(int i = 0; i < wallcontatcs.Count; i++)
    14.         {
    15.             if(wallcontatcs[i].valid == false)
    16.             {
    17.                 if(debug)
    18.                 {
    19.                     Debug.Log("RemoveContactPoint: " + wallcontatcs[i].normal.ToString());
    20.                 }
    21.                 wallcontatcs.RemoveAt(i);
    22.                 i -= 1;
    23.                 continue;
    24.             }
    25.  
    26.             Debug.DrawLine(wallcontatcs[i].point, wallcontatcs[i].point + wallcontatcs[i].normal, wallcontatcs[i].c);
    27.  
    28.             wallcontatcs[i].valid = false;
    29.         }
    30.     }
    31.  
    32.     bool AddContactPoint(Vector3 point, Vector3 normal)
    33.     {
    34.         for(int i = 0; i < wallcontatcs.Count; i++)
    35.         {
    36.             if(CustomContactPoint.Compare(wallcontatcs[i], point, normal))
    37.             {
    38.                 wallcontatcs[i].point = point;
    39.                 wallcontatcs[i].normal = normal;
    40.                 wallcontatcs[i].valid = true;
    41.                 return false;
    42.             }
    43.         }
    44.  
    45.         wallcontatcs.Add(new CustomContactPoint(point, normal, true));
    46.  
    47.         if(debug)
    48.         {
    49.             Debug.Log("AddContactPoint: " + normal.ToString());
    50.         }
    51.  
    52.         return true;
    53.     }
    54.  
    55.     bool RemoveContactPoint(Vector3 point, Vector3 normal)
    56.     {
    57.         for(int i = 0; i < wallcontatcs.Count; i++)
    58.         {
    59.             if(CustomContactPoint.Compare(wallcontatcs[i], point, normal))
    60.             {
    61.                 if(debug)
    62.                 {
    63.                     Debug.Log("RemoveContactPoint: " + normal.ToString());
    64.                 }
    65.  
    66.                 wallcontatcs.RemoveAt(i);
    67.                 return true;
    68.             }
    69.         }
    70.  
    71.         return false;
    72.     }
    73.  
    74.     void OnCollisionEnter(Collision collision)
    75.     {
    76.         if(collision.gameObject.tag == "Wall")
    77.         {
    78.             for(int i = 0; i < collision.contacts.Length; i++)
    79.             {
    80.                 AddContactPoint(collision.contacts[i].point, collision.contacts[i].normal);
    81.             }
    82.         }
    83.     }
    84.  
    85.     void OnCollisionStay(Collision collision)
    86.     {
    87.         if(collision.gameObject.tag == "Wall")
    88.         {
    89.             for(int i = 0; i < collision.contacts.Length; i++)
    90.             {
    91.                 AddContactPoint(collision.contacts[i].point, collision.contacts[i].normal);
    92.             }
    93.         }
    94.     }
    95.  
    96.     void OnCollisionExit(Collision collision)
    97.     {
    98.         if(collision.gameObject.tag == "Wall")
    99.         {
    100.             for(int i = 0; i < collision.contacts.Length; i++)
    101.             {
    102.                 RemoveContactPoint(collision.contacts[i].point, collision.contacts[i].normal);
    103.             }
    104.         }
    105.     }
    106.  
    107.     private class CustomContactPoint
    108.     {
    109.         public bool valid;
    110.         public Vector3 normal;
    111.         public Vector3 point;
    112.         public Color c;
    113.  
    114.         public CustomContactPoint(Vector3 point, Vector3 normal, bool valid)
    115.         {
    116.             this.point = point;
    117.             this.normal = normal;
    118.             this.valid = valid;
    119.  
    120.             c = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));
    121.         }
    122.  
    123.         public static bool Compare(CustomContactPoint a, Vector3 point, Vector3 normal)
    124.         {
    125.             if(a.normal == normal)
    126.             {
    127.                 return true;
    128.             }
    129.          
    130.             if(Vector3.Distance(a.point, point) < 0.01f)
    131.             {
    132.                 return true;
    133.             }
    134.  
    135.             return false;
    136.         }
    137.     }
    138. }
    139.  
     
  6. Bruchogun

    Bruchogun

    Joined:
    Sep 22, 2020
    Posts:
    1
    Hi! I had this same situation about needing to detect multiple collisions from a same collider, and this had been the only reasonable way to solve it, I think Unity should create a function that gives you all the actives colliders
     
  7. YesUnO

    YesUnO

    Joined:
    Oct 2, 2023
    Posts:
    3
    new to unity, but there is Collider[] colider = Physics.OverlapBox(); or in this case Physics2D and u should find method u need in there
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,414
    Please look at the dates of posts before responding. This is over 9 years old necro-post.

    Thanks.
     
Thread Status:
Not open for further replies.