Unity射线检测三角形面触发IndexOutOfRangeException错误求助
Unity Raycast三角形选中索引越界问题排查与修复
错误根源
- Mesh不匹配:你代码里的
mesh是从脚本挂载的物体获取的,但Raycast命中的可能是其他物体(比如你定义的cube变量),此时hit.triangleIndex是命中物体的三角形索引,用它去访问当前脚本物体的mesh.triangles数组,必然超出数组范围。 - 顶点数组不匹配:
colorArray初始化时基于当前物体的顶点数,若命中物体的顶点索引大于等于这个数组长度,直接赋值会触发索引越界。 - 潜在的MeshCollider设置问题:如果命中物体的MeshCollider勾选了
Convex,hit.triangleIndex会返回-1,同样会导致数组索引计算错误。
修正后的代码
using System.Collections.Generic; using UnityEngine; public class MyRayDraw : MonoBehaviour { private Mesh currentHitMesh; private Color[] colorArray; void Update() { if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) { // 获取命中物体的MeshFilter,跳过没有MeshFilter的物体 MeshFilter hitMeshFilter = hit.collider.GetComponent<MeshFilter>(); if (hitMeshFilter == null) { Debug.Log("命中物体没有MeshFilter组件"); return; } currentHitMesh = hitMeshFilter.mesh; int[] triangles = currentHitMesh.triangles; // 检查triangleIndex是否合法(当MeshCollider为Convex时会返回-1) if (hit.triangleIndex < 0 || hit.triangleIndex >= triangles.Length / 3) { Debug.Log("无效的三角形索引,请检查MeshCollider是否未勾选Convex"); return; } // 初始化或更新颜色数组,基于当前命中物体的顶点数 if (colorArray == null || colorArray.Length != currentHitMesh.vertices.Length) { colorArray = new Color[currentHitMesh.vertices.Length]; ResetColors(); } // 获取当前三角形的三个顶点索引 int vertIndex1 = triangles[hit.triangleIndex * 3]; int vertIndex2 = triangles[hit.triangleIndex * 3 + 1]; int vertIndex3 = triangles[hit.triangleIndex * 3 + 2]; // 标记选中的顶点为红色 colorArray[vertIndex1] = Color.red; colorArray[vertIndex2] = Color.red; colorArray[vertIndex3] = Color.red; currentHitMesh.colors = colorArray; } else { Debug.Log("未命中任何物体"); } } } // 重置所有顶点颜色为白色 private void ResetColors() { for (int k = 0; k < colorArray.Length; k++) { colorArray[k] = Color.white; } } }
关键修改点
- 每次命中后从
hit.collider获取对应物体的MeshFilter,确保使用的是命中物体的Mesh数据。 - 增加了
triangleIndex合法性检查,避免Convex MeshCollider导致的无效索引。 - 动态创建/更新
colorArray,匹配当前命中物体的顶点数量,彻底解决索引越界问题。 - 增加空值判断,防止命中无MeshFilter的物体导致空引用错误。
注意事项
- 确保命中物体挂载了MeshCollider,且未勾选
Convex(勾选Convex会无法获取有效的triangleIndex)。 - 如果需要选中多个物体,建议每次命中前先重置之前物体的颜色,避免颜色残留。
内容的提问来源于stack exchange,提问作者newCoderMe
相关产品推荐
相关产品推荐

