You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity射线检测三角形面触发IndexOutOfRangeException错误求助

Unity Raycast三角形选中索引越界问题排查与修复

错误根源

  1. Mesh不匹配:你代码里的mesh是从脚本挂载的物体获取的,但Raycast命中的可能是其他物体(比如你定义的cube变量),此时hit.triangleIndex是命中物体的三角形索引,用它去访问当前脚本物体的mesh.triangles数组,必然超出数组范围。
  2. 顶点数组不匹配:colorArray初始化时基于当前物体的顶点数,若命中物体的顶点索引大于等于这个数组长度,直接赋值会触发索引越界。
  3. 潜在的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 18:10:46