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

鼠标点击高亮Mesh三角形功能失效排查

问题:鼠标点击Mesh三角形无法修改颜色(Debug线正常)

使用legacy VertexLit shader创建了24个顶点的立方体Mesh,点击三角形时Debug线能正确高亮目标区域,但Mesh颜色无法改变。相关代码如下:

点击处理代码

void HighlightTriangle2()
{
    if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit))
    {
        return;
    }

    MeshCollider meshCollider = hit.collider as MeshCollider;
    if (meshCollider == null || meshCollider.sharedMesh == null)
    {
        return;
    }

    Debug.Log("hit.triangleIndex = " + hit.triangleIndex);

    mf.mesh = meshCollider.sharedMesh;
    Vector3[] vertices = mf.mesh.vertices;
    int[] triangles = mf.mesh.triangles;

    Vector3 p0 = vertices[triangles[hit.triangleIndex * 3 + 0]];
    Vector3 p1 = vertices[triangles[hit.triangleIndex * 3 + 1]];
    Vector3 p2 = vertices[triangles[hit.triangleIndex * 3 + 2]];

    Transform hitTransform = hit.collider.transform;
    p0 = hitTransform.TransformPoint(p0);
    p1 = hitTransform.TransformPoint(p1);
    p2 = hitTransform.TransformPoint(p2);

    //Debug.DrawLine(p0, p1, lineColor, duration);
    //Debug.DrawLine(p1, p2, lineColor, duration);
    //Debug.DrawLine(p2, p0, lineColor, duration);

    int v1 = hit.triangleIndex * 3 + 0;
    int v2 = hit.triangleIndex * 3 + 1;
    int v3 = hit.triangleIndex * 3 + 2;

    colorArray[v1] = Color.red;
    colorArray[v2] = Color.red;
    colorArray[v3] = Color.red;
    mf.mesh.colors = colorArray;
}

Mesh创建代码

private void CreateMesh()
{
    Mesh mesh = new Mesh();
    mesh.Clear();

    List<Vector3> vertList = DoVertices();
    mesh.SetVertices(vertList);

    List<int> trisList = DoTriangles(vertList);
    mesh.SetTriangles(trisList, 0);

    List<Vector2> uvsList = DoUVs_TEST();
    mesh.uv = uvsList.ToArray();

    MeshRenderer mr = GetComponent<MeshRenderer>();
    mr.material = defaultMaterial;

    Color[] colorArray = new Color[mesh.vertices.Length];
    for (int k = 0; k < mesh.vertices.Length; k++)
    {
        colorArray[k] = Color.white;
    }
    mesh.colors = colorArray;

    mf.mesh = mesh;
}

问题原因及修复方案

1. 错误操作SharedMesh

代码中mf.mesh = meshCollider.sharedMesh;直接将MeshFilter的Mesh替换为碰撞体的共享Mesh,这不仅会影响所有使用该共享Mesh的对象,还会导致后续修改的是只读的共享Mesh(无法保存修改)。应该直接操作当前MeshFilter自身的Mesh。

2. 顶点索引获取错误

你错误地将三角形索引的偏移值当作顶点索引:

int v1 = hit.triangleIndex * 3 + 0;

正确的做法是从triangles数组中取出当前三角形对应的三个顶点索引——triangles数组存储的是每个三角形的顶点索引序列,第N个三角形的三个顶点索引是triangles[N*3]、triangles[N*3+1]、triangles[N*3+2]。

3. Color数组作用域问题

CreateMesh中的colorArray是局部变量,若HighlightTriangle2中的colorArray是成员变量,需要确保它始终与当前Mesh的顶点数量匹配,并且每次修改前正确引用当前Mesh的颜色数组(或维护一份同步的数组)。


修正后的代码
// 确保colorArray是类成员变量,在CreateMesh时初始化
private Color[] colorArray;

void HighlightTriangle2()
{
    if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit))
    {
        return;
    }

    MeshCollider meshCollider = hit.collider as MeshCollider;
    if (meshCollider == null || meshCollider.sharedMesh == null)
    {
        return;
    }

    Debug.Log("hit.triangleIndex = " + hit.triangleIndex);

    // 直接操作当前MeshFilter的Mesh,而非sharedMesh
    Mesh mesh = mf.mesh;
    int[] triangles = mesh.triangles;

    // 获取当前三角形对应的三个顶点索引
    int idx0 = triangles[hit.triangleIndex * 3];
    int idx1 = triangles[hit.triangleIndex * 3 + 1];
    int idx2 = triangles[hit.triangleIndex * 3 + 2];

    // 可选:重置颜色数组为白色,只高亮当前点击的三角形
    // Array.Fill(colorArray, Color.white);

    // 修改对应顶点的颜色
    colorArray[idx0] = Color.red;
    colorArray[idx1] = Color.red;
    colorArray[idx2] = Color.red;

    // 将修改后的颜色数组赋值给Mesh
    mesh.colors = colorArray;
    // 标记Mesh需要更新,确保Unity识别到修改
    mesh.RecalculateBounds();
}

private void CreateMesh()
{
    Mesh mesh = new Mesh();
    mesh.Clear();

    List<Vector3> vertList = DoVertices();
    mesh.SetVertices(vertList);

    List<int> trisList = DoTriangles(vertList);
    mesh.SetTriangles(trisList, 0);

    List<Vector2> uvsList = DoUVs_TEST();
    mesh.uv = uvsList.ToArray();

    MeshRenderer mr = GetComponent<MeshRenderer>();
    mr.material = defaultMaterial;

    // 初始化类成员的colorArray
    colorArray = new Color[mesh.vertices.Length];
    for (int k = 0; k < mesh.vertices.Length; k++)
    {
        colorArray[k] = Color.white;
    }
    mesh.colors = colorArray;

    mf.mesh = mesh;
}

额外检查项

  • 确认你的VertexLit shader支持顶点颜色:legacy的Standard VertexLit shader默认支持,但如果是自定义shader,需要确保在顶点着色器中读取COLOR语义,并将其传递给片元着色器使用。
  • 确保MeshCollider的convex选项未勾选(除非必要),避免影响三角形索引的检测。

内容的提问来源于stack exchange,提问作者kbdev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:08:11