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

Unity中CombineMeshes合并网格丢失部分内容的原因排查

问题诊断与解决办法

1. 关闭自动顶点合并(核心解决方向)

Unity的CombineMeshes方法默认开启mergeVertices参数(值为true),会自动合并位置、法线、UV等属性完全一致的顶点。如果你的墙体拼接处存在大量重合顶点,就会导致合并后顶点数大幅减少。若这不是预期行为,显式关闭该参数:

修改合并代码:

// 最后一个参数设为false,禁止自动合并重复顶点
finalMesh.CombineMeshes(combiners, true, true, false);

参数说明:

  • 第2个参数mergeSubMeshes:设为true将所有子网格合并为单个,false则保留多子网格结构
  • 第3个参数useMatrices:设为true表示应用每个CombineInstance的变换矩阵
  • 第4个参数mergeVertices:设为false禁用自动顶点合并逻辑

2. 处理多子网格场景

如果Blender导出的FBX模型包含多个子网格(对应多材质),当前代码仅读取subMeshIndex = 0,会直接丢失其他子网格的顶点与面。需遍历每个Mesh的所有子网格:

替换核心合并逻辑:

MeshFilter[] filters = building.GetComponentsInChildren<MeshFilter>();
Mesh finalMesh = new Mesh();
finalMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;

List<CombineInstance> combiners = new List<CombineInstance>();
long totalExpectedVertices = 0;

foreach (var filter in filters)
{
    var mesh = filter.sharedMesh;
    if (mesh == null) continue;

    // 遍历所有子网格,而非仅第0个
    for (int subMeshIdx = 0; subMeshIdx < mesh.subMeshCount; subMeshIdx++)
    {
        CombineInstance ci = new CombineInstance();
        ci.subMeshIndex = subMeshIdx;
        ci.mesh = mesh;
        ci.transform = filter.transform.localToWorldMatrix;
        combiners.Add(ci);
        totalExpectedVertices += mesh.vertexCount;
    }
}

Debug.Log("Total expected vertices: " + totalExpectedVertices);
// 根据需求设置mergeVertices参数
finalMesh.CombineMeshes(combiners.ToArray(), true, true, false);
finalMesh.RecalculateNormals();

// 后续保存逻辑不变
building.AddComponent<MeshFilter>();
building.GetComponent<MeshFilter>().sharedMesh = finalMesh;
string localPath2 = buildingFolderPath + "/Building.asset";
AssetDatabase.CreateAsset(finalMesh, localPath2);
GameObject finalBuilding = PrefabUtility.SaveAsPrefabAsset(building, localPath);

3. 排查坐标精度问题

若建筑父物体离世界原点过远(数千/上万单位),Unity浮点数精度限制会导致顶点位置计算误差,原本不重合的顶点会被误判为重合合并。解决方式:

  • 临时将建筑移动到世界原点附近完成合并,再移回原位置
  • 确保Blender与Unity的单位设置一致,避免导出时出现坐标缩放误差

4. 验证Mesh读写权限

尽管你提到已开启读写权限,可在代码中额外校验:

if (!mesh.isReadable)
{
    Debug.LogError($"Mesh {mesh.name} 不可读!请在导入设置中开启Read/Write Enabled");
    continue;
}

Blender导出FBX时需勾选完整几何体选项,Unity导入设置中确保Mesh > Read/Write Enabled设为true。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:18:17