- Home /
Finding if point is contained within irregular mesh
Is there something like bounds.Contain() that instead of returning true if a point is contained within a bounding box, returns true if the point is within the volume defined by the mesh collider? (So it would work if the mesh was a doughnut shape)
Check out this answer to a similar question: http://answers.unity3d.com/questions/611947/am-i-inside-a-volume-without-colliders.html#answer-832969
Answer by Eric5h5 · Feb 18, 2011 at 10:27 AM
There's nothing built-in, but you can make whatever functions you want. See here for a function that checks if a point is inside an arbitrary 2D shape.
edit (copy from wiki)
 // Poly.cs
 using UnityEngine;
  
 public static class Poly
 {
     public static bool ContainsPoint(Vector2[] polyPoints, Vector2 p)
     {
         var j = polyPoints.Length - 1;
         var inside = false;
         for (int i = 0; i < polyPoints.Length; j = i++)
         {
             var pi = polyPoints[i];
             var pj = polyPoints[j];
             if (((pi.y <= p.y && p.y < pj.y) || (pj.y <= p.y && p.y < pi.y)) &&
                 (p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x))
                 inside = !inside;
         }
         return inside;
     }
 }
Eric, how in the world did you come up with that function? Totally sweet!
The Unity wiki does no longer exist. However we have the wayback machine (archive.org). So I fixed the link, again ^^.
Answer by IsGreen · Feb 05, 2014 at 08:20 PM
Script Action Video: http://www.youtube.com/watch?v=O2xcTvWBRiU#t=0
 using UnityEngine;
 using System.Collections;
 
 public class csObject : MonoBehaviour {
 
     public MeshCollider meshCollider;
     public bool In;
     public bool concaveHull;
     public float distance=100f;
 
     Ray right,left,up,down,forward,back,tempRay;
     bool r,l,u,d,f,b;
 
     RaycastHit rightHit   = new RaycastHit();
     RaycastHit leftHit    = new RaycastHit();
     RaycastHit upHit      = new RaycastHit();
     RaycastHit downHit    = new RaycastHit();
     RaycastHit forwardHit = new RaycastHit();
     RaycastHit backHit    = new RaycastHit();
     RaycastHit tempHit    = new RaycastHit();
 
     void Start(){
 
         right   = new Ray(Vector3.zero , -Vector3.right);
         left    = new Ray(Vector3.zero , -Vector3.left);
         up      = new Ray(Vector3.zero , -Vector3.up);
         down    = new Ray(Vector3.zero , -Vector3.down);
         forward = new Ray(Vector3.zero , -Vector3.forward);
         back    = new Ray(Vector3.zero , -Vector3.back);
         tempRay = new Ray();
 
     }
 
     bool ConcaveHull(Ray ray, RaycastHit hit){
 
 
         tempRay.origin = transform.position;
         tempRay.direction = -ray.direction;
         float customDistance = distance-hit.distance;
         int lastPoint = hit.triangleIndex;
 
         while(meshCollider.Raycast(tempRay, out tempHit, customDistance)){
 
             if(tempHit.triangleIndex == lastPoint) break;
             lastPoint = tempHit.triangleIndex;
             customDistance = tempHit.distance;
             ray.origin = -ray.direction * customDistance + transform.position;
 
             if(!meshCollider.Raycast(ray, out tempHit, customDistance)) {
 
                 concaveHull = true;
                 return true;
 
             }
 
             if(tempHit.triangleIndex == lastPoint) break;
             lastPoint = tempHit.triangleIndex;
             customDistance -= tempHit.distance;
 
         }
 
         return false;
 
     }
 
     // Update is called once per frame
     void FixedUpdate () {
     
         right.origin   = -right.direction   * distance + transform.position;
         left.origin    = -left.direction    * distance + transform.position;
         up.origin      = -up.direction      * distance + transform.position;
         down.origin    = -down.direction    * distance + transform.position;
         forward.origin = -forward.direction * distance + transform.position;
         back.origin    = -back.direction    * distance + transform.position;
 
         r = meshCollider.Raycast(right   , out rightHit   , distance);
         l = meshCollider.Raycast(left    , out leftHit    , distance);
         u = meshCollider.Raycast(up      , out upHit      , distance);
         d = meshCollider.Raycast(down    , out downHit    , distance);
         f = meshCollider.Raycast(forward , out forwardHit , distance);
         b = meshCollider.Raycast(back    , out backHit    , distance);
 
         if(r&&l&&u&&d&&f&&b) {
 
             if(ConcaveHull(right,rightHit))          In = false;
             else if(ConcaveHull(left,leftHit))       In = false;
             else if(ConcaveHull(up,upHit))           In = false;
             else if(ConcaveHull(down,downHit))       In = false;
             else if(ConcaveHull(forward,forwardHit)) In = false;
             else if(ConcaveHull(back,backHit))       In = false;
             else { In = true; concaveHull = false; }
 
         } else In=false;
     
     }
 
 }
It works very well for non-convex mesh colliders - contrary to Physics.CheckSphere. Just what I was looking for!
Answer by tyjkenn · Jul 03, 2013 at 10:43 PM
Physics.CheckSphere is what you need. Just use a small test sphere like so:
 if(Physics.CheckSphere(testPosition,.0001)){
     //It is in a collider
 } else{
     //It is not in a collider
 }
This does only work if the sphere intersects the surface of a mesh and not if it is fully inside.
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
               
 
			 
                