Search code examples
3dunity-game-enginecollision-detectionintersection

Unity3D: detect triangles of mesh intersects with other gameObject


I'm have plane, contains multiple meshes (as usually). Now, I added to scene new gameObject - Cylinder. When cylinder collides with plane, I need to detect all triangles of plane, that appears inside of Cylinder. Is it possible with Unity3D API?
I saw tutorial "Colliders as Triggers", but I have one question - can I handle Trigger event without Rigidbody component in colliding objects? By some reasons I can't have Rigidbody in plane and in cylinder.


Solution

  • This can be accomplished by adding a spherecast to the cylinder and when any object enters it ( a box collider, raycast, etc ) have some event occur. For detecting the triangles of the plane ( assuming you have some sort of mesh collider ) you can get a list of all hit objects within the cylinder's spherecast and cycle through each one that composes a complete mesh triangle. Here's some code to show the process:

    void GetMeshTriangle(RaycastHit meshHitPoint, MeshCollider meshObject)
    {
        Mesh mesh = meshObject.sharedMesh;
        Vector3[] vertices = mesh.vertices;
        int[] triangles = mesh.triangles;
        int counter = 0;
        for(int n = 0; n <= worldObjectsHit.Length * 3; n++)
        {
            if (counter == 2)
            {
                Transform hitTransform = meshHitPoint.collider.transform;
                try
                {
                    Vector3 pointOne = vertices[triangles[meshHitPoint.triangleIndex * 3 + n]];
                    Vector3 pointTwo = vertices[triangles[meshHitPoint.triangleIndex * 3 + (n - 1)]];
                    Vector3 pointThree = vertices[triangles[meshHitPoint.triangleIndex * 3 + (n - 2)]];
                    pointOne = hitTransform.TransformPoint(pointOne);
                    pointTwo = hitTransform.TransformPoint(pointTwo);
                    pointThree = hitTransform.TransformPoint(pointThree);
                    Vector3 meshObjectCenter = new Vector3((( pointOne.x + pointTwo.x + pointThree.x ) / 3 ), 
                                                   ((pointOne.y + pointTwo.y + pointThree.y) / 3) , 
                                                   ((pointOne.z + pointTwo.z + pointThree.z) / 3));
                    Debug.DrawLine(p0, p1);
                    Debug.DrawLine(p1, p2);
                    Debug.DrawLine(p2, p0);
                    IsMeshColliding(meshHitPoint, meshObjectCenter);
                } 
                catch (System.IndexOutOfRangeException ex)
                {
                    break;
                }
                counter = 0;
            } 
            else 
            {
                counter++;
            }
        }
    }
    

    At the line "IsMeshColliding( )" you can add in your own logic to have some sort of event occur.