# How to find a material through a raycast in Unity 5?

I have an empty object with a script on it and I want to be able to move the empty over other objects and then have it print out the name of the material for the triangle that it's hovering above. (Its for something else, but I only need help getting to that stage, I can do the rest from that point). I found this on the topic but the answer is very vauge. I finished steps 1 and 2 but I can't figure out number 3. Here is my code so far...

void Update (){
Ray ray = new Ray(transform.position, new Vector3(0, -100, 0));
RaycastHit hit;

if(Physics.Raycast(ray, out hit)){
print ("Triangle Index: " + hit.triangleIndex);

Mesh mesh = hit.collider.gameObject.GetComponent<MeshFilter>().mesh;

print ("Submesh Count: " + mesh.subMeshCount);
}
}


Could someone show me how to finish it off so that when I move the empty over different objects, it would print out the name of the material per triangle?

Thanks, Matthew

I'd recommend testing empirically to confirm, but the second answer at this link says that triangle data for submeshes is indexed sequentially in order of submesh index. That means all the triangles for submesh 0 have lower indices than those in submesh 1, etc...

So, you can iterate over the submeshes until you find the one your triangle belongs within:

MeshCollider collider = hit.collider as MeshCollider;
// Remember to handle case where collider is null because you hit a non-mesh primitive...

Mesh mesh = collider.sharedMesh;

// There are 3 indices stored per triangle
int limit = hit.triangleIndex * 3;
int submesh;
for(submesh = 0; submesh < mesh.subMeshCount; submesh++)
{
int numIndices = mesh.GetTriangles(submesh).Length;
if(numIndices > limit)
break;

limit -= numIndices;
}

Material material = collider.GetComponent<MeshRenderer>().sharedMaterials[submesh];


This is pretty ugly, but still neater than the accepted answer at that link, which visits every triangle to test if it's the one the ray hit. ;)