kingBook

导航

判断鼠标点击模型时,鼠标所接触的材质

当一个MeshRenderer拥有多个材质时,MeshRenderer.materials中的索引与子网格的索引相对应,所以只需要找到子网格的索引就能找到材质的索引。

using UnityEngine;

public class TestRaycastHitMaterial:MonoBehaviour{
	
	private void Update() {
		if(!Input.GetMouseButtonDown(0))return;
		var meshRenderer=GetComponent<MeshRenderer>();
		var meshFilter=GetComponent<MeshFilter>();
		var mesh=meshFilter.mesh;

		var ray=Camera.main.ScreenPointToRay(Input.mousePosition);
		RaycastHit hitInfo;
		Physics.Raycast(ray,out hitInfo);

		if(hitInfo.collider!=null){
			int subMeshIndex=MeshUtil.getRaycastHitSubMeshIndex(mesh,hitInfo);
			Debug.Log(subMeshIndex);
			//Debug.Log(meshRenderer.materials[subMeshIndex]);
		}
	}

	/// <summary>
	/// 返回射线命中的子网格索引号
	/// <br>如果没有子网格或未成功匹配则返回-1</br>
	/// </summary>
	/// <param name="mesh"></param>
	/// <param name="hitInfo"></param>
	/// <returns></returns>
	private int getRaycastHitSubMeshIndex(Mesh mesh,RaycastHit hitInfo){
		//命中三角形的顶点索引
		int[] triangles=mesh.triangles;
		int triangleIndex=hitInfo.triangleIndex;
		int i0=triangles[triangleIndex*3];
		int i1=triangles[triangleIndex*3+1];
		int i2=triangles[triangleIndex*3+2];
		
		int subMeshCount=mesh.subMeshCount;
		for(int i=0;i<subMeshCount;i++){
			var indices=mesh.GetIndices(i);
			int vertexCount=indices.Length;
			for(int j=0;j<vertexCount;j+=3){
				int j0=indices[j];
				int j1=indices[j+1];
				int j2=indices[j+2];
				//如果子网格的索引与命中三角形匹配,则表示是命中的子网格
				if(i0==j0&&i1==j1&&i2==j2){
					return i;
				}
			}
		}
		return -1;
	}
}

posted on 2019-08-26 11:31  kingBook  阅读(198)  评论(0编辑  收藏  举报