Check if position is inside a collider

Hey all,

This is for a teleport feature.

I am about to write a function that returns if a position is inside of a collider.That way I can negate the teleport, so the player doesn't go inside of objects.

Does unity have some magic way of doing this? I have an idea of how I can do it, but I wanted to ask here first in case there was an built in way / simple way one of you guys knew of.

Thanks

Guys I found a good simple way of doing this. Thanks for the responses. Here is a hunk of code

I used a sweeptest on my rigidbody, I used distance and direction of my teleport location and used it as the ray to send out. I tested the what my RaycastHit got assigned to like this.

if(hitToTest.collider.bounds.Contains(telePosition))
{
   print("point is inside collider");
}

Check out unity SweepTest() and Collider.bounds for specific syntax and what not

Almost same: we used in the end:

 public static bool IsInside(Collider c, Vector3 point)
    	{
    		Vector3 closest = c.ClosestPoint(point);
    		// Because closest=point if point is inside - not clear from docs I feel
    		return closest == point;
    	}

@s4vi0r has a good solution if you’re using box colliders, but a lot of us are asking about colliders in general, which would include spheres, capsules, and mesh colliders.
The solution bellow should account for these in a generic manner.


I should note that MeshColliders marked for triggers must also be marked convex, for similar reasons the MeshColliders you check with this code must also be convex or you may recieve eroneous results.

However this code could be modified for an IsBelow() method for use with static MeshColliders you might have for terrain.


bool IsWithin(Collider c, Vector3 point, bool useRigidbody)
{
    Vector3 closest = c.ClosestPoint(point);
    Vector3 origin = c.transform.position + (c.transform.rotation * c.bounds.center);

    Vector3 originToContact = closest-origin;
    Vector3 pointToContact = closest-point;

    // If you're checking if a point is within a moving rigidbody and want to use it instead (ideally a single collider rigidbody; multiple could move the center of mass between the colliders, placing it "outside" and returning false positives). 
    Rigidbody r = c.attachedRigidbody;
    if (useRigidbody && (r != null))
    {
        // The benefit of this is the use of the center of mass for a more accurate physics origin; we multiply by rotation to convert it from it's local-space to a world offset.
        originToContact = closest - (r.position + (r.rotation * r.centerOfMass));
    }

    // Here we make the magic, originToContact points from the center to the closest point. So if the angle between it and the pointToContact is less than 90, pointToContact is also looking from the inside-out.
    // The angle will probably be 180 or 0, but it's bad to compare exact floats and the rigidbody centerOfMass calculation could add some potential wiggle to the angle, so we use "< 90" to account for any of that.
    return (Vector3.Angle(originToContact, pointToContact) < 90);
}

See this solution if you’re looking to do checks on concave MeshColliders, but it’s certainly overkill otherwise so pick the solution that works for you.

You can use triggers to check if objects are colliding. In the collider inspector of your object, turn on 'Is Trigger'. Then you can create a script on your object that sends out values using the OnTriggerEnter(){}, OnTriggerStay(){} and OnTriggerExit(){} functions.

Edit: You could make your teleport OnTriggerEnter(){} function modify the location of the character easily. You can access your players location from that function and change it.

Make sure one of the colliding objects is a rigidBody, since it wont trigger with an other static collider. Checl the Collision action matrix here for more information on triggers and what will trigger them.

Also, the 3d platform tutorial covers teleports IRC. Their solution might be more complete than mine, can't remember how they did it though.

What you need is OverlapPoint():

Collider2D collider;
Vector2 point;
if(collider.OverlapPoint(point)){
   //do stuff
}