Skip to content

Instantly share code, notes, and snippets.

@MuhammadFaizanKhan
Created May 2, 2024 06:02
Show Gist options
  • Save MuhammadFaizanKhan/511be424ccbf1b785621b2aba0f2c9bf to your computer and use it in GitHub Desktop.
Save MuhammadFaizanKhan/511be424ccbf1b785621b2aba0f2c9bf to your computer and use it in GitHub Desktop.
If you have a single mesh renderer component containing a list of materials and you need to detect the correct material (or sub-mesh) at runtime upon a mouse click, then this script is exactly what you need. Simply attach this script to any game object. Ensure that the object requiring material selection has a collider component attached
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MaterialPickOnClick : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit))
{
MeshRenderer meshRenderer = hit.collider.GetComponent<MeshRenderer>();
if (meshRenderer != null)
{
MeshFilter meshFilter = hit.collider.GetComponent<MeshFilter>();
Mesh mesh = meshFilter.mesh;
int totalSubMesh = mesh.subMeshCount;
Debug.Log(hit.collider.gameObject.name + " SubMeshCount " + totalSubMesh);
int[] subMeshesFaceTotals = new int[totalSubMesh];
for (int i = 0; i < totalSubMesh; i++)
{
subMeshesFaceTotals[i] = mesh.GetTriangles(i).Length / 3;
}
int hitSubMehsNumber = 0;
int maxVal = 0;
for (int i = 0; i < totalSubMesh; i++)
{
maxVal += subMeshesFaceTotals[i];
if(hit.triangleIndex <= maxVal - 1)
{
hitSubMehsNumber = i + 1;
break;
}
}
Debug.Log("We hit sub mesh number: " + meshRenderer.sharedMaterials[hitSubMehsNumber-1].name);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment