Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Composite Collider 2d bound

Discussion in '2D' started by rkoshak, Jan 9, 2018.

  1. rkoshak

    rkoshak

    Joined:
    Dec 1, 2014
    Posts:
    9
    We are using the composite collider as triggers in our tilemap to define ladders. The problem is trying to get data on the specific 'ladder' we are colliding with. I would normally store the collider in OnTriggerEnter and use the bounds to determine center, top and bottom of the ladder, but with using the composite collider, all the tiles in the tilemap are used to determine bounds.

    Is there a way to get data on the specific, single collider that we are hitting and not the entire tilemap object?

    Thanks
     
    Sarchophagi likes this.
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    When you collide with the composite, you should be able to do an overlap point check to find any collider components at that location.

    untested, but this is the idea:
    Code (CSharp):
    1. void OnCollisionEnter2D(Collision2D collision) {
    2.  
    3.     // if the collider is a composite, get any colliders underneath that tile
    4.     if (collision.collider is CompositeCollider2D) {
    5.  
    6.         List<Collider2D> hitColliders = new List<Collider2D>();
    7.         Vector3 hitPosition = Vector3.zero;
    8.  
    9.         foreach (ContactPoint2D hit in collision.contacts) {
    10.             // move the hit location inside the collider a bit
    11.             hitPosition.x = hit.point.x - 0.01f * hit.normal.x;
    12.             hitPosition.y = hit.point.y - 0.01f * hit.normal.y;
    13.             hitColliders.AddRange(Physics2D.OverlapPointAll(hitPosition));
    14.         }
    15.    
    16.         // use hitColliders as a list of all colliders under the hit location
    17.     }
    18. }
     
  3. rkoshak

    rkoshak

    Joined:
    Dec 1, 2014
    Posts:
    9
    Thanks Jeffrey. Only saw this today. Wish I had been notified of a response.
     
    LiterallyJeff likes this.
  4. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    No problem. This is the same technique used in the Bricks demo in the Unity 2D extras:
    https://github.com/Unity-Technologies/2d-extras
     
  5. Sarchophagi

    Sarchophagi

    Joined:
    Nov 14, 2014
    Posts:
    5
    Hello. I have the same problem here but can't get @jeffreyschoch solution to work because I don't have collision.contacts once I am dealing with OntriggerEnter2D event. Any other suggestions?
     
  6. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    @Sarchophagi

    I haven't tested this but you can probably do something like this:
    Code (CSharp):
    1. private Collider2D _collider2D;
    2.  
    3. private void Awake()
    4. {
    5.     _collider2D = GetComponent<Collider2D>();
    6. }
    7.  
    8. private void OnTriggerEnter2D(Collider2D other)
    9. {
    10.     if (other is CompositeCollider2D)
    11.     {
    12.         List<Collider2D> hitColliders = new List<Collider2D>();
    13.  
    14.         // get info about the shortest distance between the two colliders
    15.         ColliderDistance2D colliderDistance = _collider2D.Distance(other);
    16.  
    17.         if (!colliderDistance.isValid)
    18.         {
    19.             return;
    20.         }
    21.  
    22.         Vector2 hitPoint;
    23.  
    24.         // if its overlapped then this collider's nearest vertex is inside the other collider
    25.         // so the position adjustment shouldn't be necessary
    26.         if (colliderDistance.isOverlapped)
    27.         {
    28.             hitPoint = colliderDistance.pointA; // point on the surface of this collider
    29.         }
    30.         else
    31.         {
    32.             hitPoint = colliderDistance.pointB; // point on the surface of the other collider
    33.  
    34.             Vector3 hitPosition = Vector3.zero;
    35.             Vector2 normal = colliderDistance.normal;
    36.  
    37.             // move the hit location inside the collider a bit
    38.             // this assumes the colliders are basically touching
    39.             hitPoint -= 0.01f * normal;
    40.         }
    41.  
    42.         hitColliders.AddRange(Physics2D.OverlapPointAll(hitPoint));
    43.         // use hitColliders as a list of all colliders under the hit location
    44.     }
    45. }
    You could also raycast from one collider's center to the other collider's center, which would probably be enough.