Get Material of individual triangle

I have an object which has touchable and non-touchable areas.

I currently work this by splitting the object into two meshes in Blender before importing to Unity. To detect, I Raycast and if we hit the mesh designated ‘touchable’ then (do touchy stuff)…

This works but it’s not ideal. What I really want is to get the material of the individual triangle hit by Raycast, so I can use one object - with two different materials assigned to it for touchable and non-touchable surfaces.

I’ve tried

Var FaceIndex = hit.triangleIndex*3

But trying to get the material of the face with

FaceIndex.renderer.material gives an error.

Any pointers would be most welcome!

Depending on the type of object you are using, you may be able to use one mesh but have two different colliders for the touchable and non-touchable areas (or perhaps just not have a collider on the non-touchable area at all). You can compare the collider returned in the RaycastHit with a reference to the touchable collider:-

var hit: RaycastHit;

if (hit.collider == touchableCollider) {
   // Process the touch.
}

Thanks, I already scripted it using two different colliders but I’d prefer to be able to detect the material on the exact face - so I can use that material on as many different objects as I need without having to add or modify the code to include new checks for touchable colliders.

At the moment I am doing the check via colliders / object tag.

I can get the material of a hit collider, but not of an individual face unfortunately.

Same exact question for me… is there a solution ?
Some of my objects have several materials…

Unfortunately there is no direct way of doing this. However, RaycastHit has a member called triangleIndex. Using Mesh.GetTriangles, you can look through each submesh to find a matching triangle index. Assuming that your submeshes do not share any triangles, then you should only find the triangle once, and you’ll know the submesh index.

Ok, and the submesh index should be equal to the (picked) material index in the MeshRenderer material list.
got it, I try it now.
Thank you very much.

public static int GetSubMeshIndex(Mesh mesh, int triangleIndex)
        {
            if (mesh.isReadable == false)
            {
                Debug.LogError("You need to mark model's mesh as Read/Write Enabled in Import Settings.", mesh);
                return 0;
            }

            int triangleCounter = 0;
            for (int subMeshIndex = 0; subMeshIndex < mesh.subMeshCount; subMeshIndex++)
            {
                var indexCount = mesh.GetSubMesh(subMeshIndex).indexCount;
                triangleCounter += indexCount / 3;
                if (triangleIndex < triangleCounter)
                {
                    return subMeshIndex;
                }
            }

            Debug.LogError(
                $"Failed to find triangle with index {triangleIndex} in mesh '{mesh.name}'. Total triangle count: {triangleCounter}",
                mesh);
            return 0;
        }

thanks so much . you save my time

Hello, I’m also studying how to get the material information of a triangle of the model in unity recently. Have you solved this problem?