You can get the Material of a line trace hit, or rather, where the closest vertex index is to a line trace hit.
It requires some c++ but it isn’t too hard.
Firstly get all meshVertexPositions by calling ComputeSkinPositions, example from my code where meshVertexPositionsArray is a TArray defined in .h:
TArray<FMatrix> matrixArrayTemp;
const FSkeletalMeshLODRenderData& skelMeshRenderDataTemp = vertexPaintSkelComponent->GetSkeletalMeshRenderData()->LODRenderData[0];
FSkinWeightVertexBuffer& skinWeightBufferTemp = *vertexPaintSkelComponent->GetSkinWeightBuffer(0); // Får crash med array out of bounds 46 of 0
vertexPaintSkelComponent->CacheRefToLocalMatrices(matrixArrayTemp);
vertexPaintSkelComponent->ComputeSkinnedPositions(vertexPaintSkelComponent, meshVertexPositionsArray, matrixArrayTemp, skelMeshRenderDataTemp, skinWeightBufferTemp);
Then you loop through them to check the distance from the line trace Hit Location and save the closest index. Remember that the meshVertexPositions you get is local to the skeletal mesh component, not to the actor local space which is why i do some transforms here. Looping through them in code is not as expensive as you may think, this is from a vertex color and detection plugin where i’ve stresstested looping through 48k verts from paragon characters every frame and worked well:
FVector hitLocationInActorLocalTemp = UKismetMathLibrary::InverseTransformLocation(actor->GetTransform(), paintOnMeshSettings.location);
for (int i = 0; i < meshVertexPositionsArray.Num(); i++) {
meshVertexInActorLocalSpaceTemp = UKismetMathLibrary::InverseTransformLocation(actor->GetTransform(), UKismetMathLibrary::TransformLocation(vertexPaintSkelComponent->GetComponentTransform(), meshVertexPositionsArray[i]));
if ((hitLocationInActorLocalTemp - meshVertexInActorLocalSpaceTemp).Size() < closestDistanceTOClosestVertexTemp) {
closestDistanceTOClosestVertexTemp = (hitLocationInActorLocalTemp - meshVertexInActorLocalSpaceTemp).Size();
closestVertIndexTest = i;
}
}
Then you get section from vertex index and just use GetMaterial :
const FSkeletalMeshLODRenderData& skelMeshRenderDataTemp = skelMesh->GetSkeletalMeshRenderData()->LODRenderData[0];
int sectionIndexTemp;
int verIndexTemp;
skelMeshRenderDataTemp.GetSectionFromVertexIndex(vertIndex, sectionIndexTemp, verIndexTemp);
return skelMesh->GetMaterial(skelMeshRenderDataTemp.RenderSections[sectionIndexTemp].MaterialIndex);
Hope this helps!