Composite Collider 2d bound

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

1 Like

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:

void OnCollisionEnter2D(Collision2D collision) {

    // if the collider is a composite, get any colliders underneath that tile
    if (collision.collider is CompositeCollider2D) {

        List<Collider2D> hitColliders = new List<Collider2D>();
        Vector3 hitPosition = Vector3.zero;

        foreach (ContactPoint2D hit in collision.contacts) {
            // move the hit location inside the collider a bit
            hitPosition.x = hit.point.x - 0.01f * hit.normal.x;
            hitPosition.y = hit.point.y - 0.01f * hit.normal.y;
            hitColliders.AddRange(Physics2D.OverlapPointAll(hitPosition));
        }
    
        // use hitColliders as a list of all colliders under the hit location
    }
}

Thanks Jeffrey. Only saw this today. Wish I had been notified of a response.

1 Like

No problem. This is the same technique used in the Bricks demo in the Unity 2D extras:
https://github.com/Unity-Technologies/2d-extras

Hello. I have the same problem here but can’t get @LiterallyJeff solution to work because I don’t have collision.contacts once I am dealing with OntriggerEnter2D event. Any other suggestions?

@Sarchophagi

I haven’t tested this but you can probably do something like this:

private Collider2D _collider2D;

private void Awake()
{
    _collider2D = GetComponent<Collider2D>();
}

private void OnTriggerEnter2D(Collider2D other)
{
    if (other is CompositeCollider2D)
    {
        List<Collider2D> hitColliders = new List<Collider2D>();

        // get info about the shortest distance between the two colliders
        ColliderDistance2D colliderDistance = _collider2D.Distance(other);

        if (!colliderDistance.isValid)
        {
            return;
        }

        Vector2 hitPoint;

        // if its overlapped then this collider's nearest vertex is inside the other collider
        // so the position adjustment shouldn't be necessary
        if (colliderDistance.isOverlapped)
        {
            hitPoint = colliderDistance.pointA; // point on the surface of this collider
        }
        else
        {
            hitPoint = colliderDistance.pointB; // point on the surface of the other collider

            Vector3 hitPosition = Vector3.zero;
            Vector2 normal = colliderDistance.normal;

            // move the hit location inside the collider a bit
            // this assumes the colliders are basically touching
            hitPoint -= 0.01f * normal;
        }

        hitColliders.AddRange(Physics2D.OverlapPointAll(hitPoint));
        // use hitColliders as a list of all colliders under the hit location
    }
}

You could also raycast from one collider’s center to the other collider’s center, which would probably be enough.