Remove Triangle From Sphere When Collided With Problem

I have put together this script which is supposed to remove a triangle from a sphere when collided with. It works intermittently. Sometimes when a triangle/face of a sphere is collided with, the triangle does not get removed until I hit some different part of the triangle.

The sphere has a Mesh Collider with Convex unchecked.
The shot object has a sphere collider with a rigidbody. The collision detection is on Discrete.

Here’s my code:

    void OnCollisionEnter(Collision collisionInfo)
    {
        var mesh = gameObject.GetComponent<MeshFilter>().mesh;
        MeshCollider tmpCol = gameObject.GetComponent<MeshCollider>();

        int[] triangles = mesh.triangles;

        for (var i = 0; i < collisionInfo.contacts.Length; i++)
        {
            RaycastHit hit;
            Collider col = GetComponent<Collider>();
            col.Raycast(new Ray(collisionInfo.contacts[i].point, collisionInfo.contacts[i].normal), out hit, collisionInfo.contacts[i].point.magnitude);

            if (hit.collider != null && hit.triangleIndex != -1)
            {
                triangles = removeTriangle(hit.triangleIndex, triangles);
            }
        }

        mesh.triangles = triangles;
        tmpCol.sharedMesh = mesh;
    }

    private int[] removeTriangle(int triangle, int[] tris)
    {
        for (var i = triangle * 3; i < tris.Length - 3; ++i)
        {
            if (tris[i] == -1) break;
            tris[i] = tris[i + 3];
        }
        return tris;
    }

If I understand this correctly, you’re casting a ray out from the point of contact along it’s normal and removing any triangle it hits? Just visualizing that makes me think that it’d only work if the hit point ended up in front of the face of the triangle you’re trying to remove. Since collision detection isn’t perfect and overlap does happen I’d bet you’re running into the case where the hit point is behind the triangle.

As an aside, you might consider moving the GetComponent out of the for loop, and maybe even all of them out of OnCollisionEnter altogether since they only need to be got once.