How to Physics.CheckCylinder?

Just like Physics.CheckCapsule or Physics.CheckBox, what I need is a method that can check for collisions on a Cylinder area. Is there anything like that? Or how can I achieve it?

Unity doesn’t have a cylinder collider type. That’s mainly because a cylinder is more difficult to describe as a mathematical formula. A capsule is easier since it’s just two connected spheres. The best workaround is to use a combination of a capsule and a box.

Make sure the box collider is actually large enough to enclose the whole cylinder section. Also make sure the “caps” of the capsule are not included. Something like this:

97204-cylindercollidercheck.png

This should do what you want:

public static bool CheckCylinder(Vector3 aStart, Vector3 aEnd, float aRadius, int aLayerMask, QueryTriggerInteraction aQueryTriggerInteraction)
{
    if (!Physics.CheckCapsule(aStart, aEnd, aRadius, aLayerMask, aQueryTriggerInteraction))
        return false;
    Vector3 dir = aEnd - aStart;
    return Physics.CheckBox(aStart + dir * 0.5f, new Vector3(aRadius, aRadius, dir.magnitude*0.5f), Quaternion.LookRotation(dir), aLayerMask, aQueryTriggerInteraction);
}

This let you specify the top center point and the bottom center point of your cylinder and the radius. It will only return true when an object overlaps with both colliders.

It’s not perfect as it has some edge cases where a large object at a 45! angle might touch both colliders but is still outside the cylinder. You can’t really get a perfect match with the available methods. However you can increase the precision by using another box that is 45° rotated along the cylinder axis. That would “flatten” the edges of the two boxes.

97206-cylindercollidercheck2.png

public static bool CheckCylinder(Vector3 aStart, Vector3 aEnd, float aRadius, int aLayerMask, QueryTriggerInteraction aQueryTriggerInteraction)
{
    if (!Physics.CheckCapsule(aStart, aEnd, aRadius, aLayerMask, aQueryTriggerInteraction))
        return false;
    Vector3 dir = aEnd - aStart;
    Quaternion q = Quaternion.LookRotation(dir);
    if (!Physics.CheckBox(aStart + dir * 0.5f, new Vector3(aRadius, aRadius, dir.magnitude*0.5f), q, aLayerMask, aQueryTriggerInteraction))
        return false;
    q = Quaternion.AngleAxis(45, dir) * q;
    if (!Physics.CheckBox(aStart + dir * 0.5f, new Vector3(aRadius, aRadius, dir.magnitude*0.5f), q, aLayerMask, aQueryTriggerInteraction))
        return false;
    return true;
}

Of course this “rotation” of the boxes could be made smaller and smaller and you would use more and more boxes to increase precision.

edit Probably the best solution would be this one:

public static bool CheckCylinder(Vector3 aStart, Vector3 aEnd, float aRadius, int aLayerMask, QueryTriggerInteraction aQueryTriggerInteraction)
{
    if (!Physics.CheckCapsule(aStart, aEnd, aRadius, aLayerMask, aQueryTriggerInteraction))
        return false;
    Vector3 dir = aEnd - aStart;
    Quaternion q = Quaternion.LookRotation(dir);
    Quaternion q2 = Quaternion.AngleAxis(45f, dir);
    Vector3 size = new Vector3(aRadius, aRadius / (1f + Mathf.Sqrt(2f)), dir.magnitude * 0.5f);
    for (int i = 0; i < 4; i++)
    {
        if (Physics.CheckBox(aStart + dir * 0.5f, size, q, aLayerMask, aQueryTriggerInteraction))
            return true;
        q = q2 * q;
    }
    return false;
}

It uses one capsule and 4 boxes. The 4 boxes actually form an octagon on the outside of the capsule. In this case we need a collision with the capsule and any of the boxes. I can’t attach another image so i post it as comment below.

There is no CheckCylinder, but you could check for a capsule that extends beyond the cap of the cylinder, and then also check for a box that aligns with the caps of the cylinder. If both checks pass, you have a cylinder collision.

97205-checkcylinder.png