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

Unity中合并MRT扫描生成的大量切片网格的问题求助

解决Unity中大量MRT切片网格合并问题

我之前处理过类似的医疗3D模型导入后的合并需求,Mesh Combine Wizard在子物体数量爆炸时确实会遇到性能或上限问题,给你几个实用的方案:

一、自定义C#合并脚本(最可控,适合大量子物体)

自己写脚本可以针对性优化,避开第三方工具的限制,尤其适合几百甚至上千个MeshPart的场景。

脚本思路:

  1. 遍历default对象下所有带MeshFilter的子物体
  2. 收集所有网格数据到CombineInstance数组
  3. 创建新的合并网格,替换原父物体的网格(或生成新物体)
  4. 清理原有的子物体

示例脚本:

using UnityEngine;
using UnityEditor;

public class MassMeshCombiner : EditorWindow
{
    [MenuItem("Tools/Combine Mass Meshes")]
    public static void ShowWindow()
    {
        GetWindow<MassMeshCombiner>("Mass Mesh Combiner");
    }

    private void OnGUI()
    {
        if (Selection.activeTransform == null)
        {
            EditorGUILayout.LabelField("请选择要合并的父物体(比如default)");
            return;
        }

        if (GUILayout.Button("开始合并"))
        {
            CombineMeshes(Selection.activeTransform);
        }
    }

    private void CombineMeshes(Transform parent)
    {
        // 收集所有子物体的MeshFilter
        MeshFilter[] meshFilters = parent.GetComponentsInChildren<MeshFilter>(true);
        CombineInstance[] combineInstances = new CombineInstance[meshFilters.Length];

        // 记录材质(假设所有子物体用同一种材质,若不同需按材质分组)
        Material sharedMaterial = null;

        for (int i = 0; i < meshFilters.Length; i++)
        {
            if (meshFilters[i].sharedMesh == null) continue;
            
            combineInstances[i].mesh = meshFilters[i].sharedMesh;
            combineInstances[i].transform = meshFilters[i].transform.localToWorldMatrix;

            if (sharedMaterial == null)
            {
                sharedMaterial = meshFilters[i].GetComponent<MeshRenderer>().sharedMaterial;
            }
        }

        // 创建新网格
        Mesh combinedMesh = new Mesh();
        combinedMesh.CombineMeshes(combineInstances, true, true);
        combinedMesh.name = "Combined_MRT_Mesh";

        // 处理父物体:移除原有子物体,添加合并后的网格
        foreach (Transform child in parent)
        {
            DestroyImmediate(child.gameObject);
        }

        MeshFilter parentFilter = parent.GetComponent<MeshFilter>();
        if (parentFilter == null) parentFilter = parent.gameObject.AddComponent<MeshFilter>();
        parentFilter.sharedMesh = combinedMesh;

        MeshRenderer parentRenderer = parent.GetComponent<MeshRenderer>();
        if (parentRenderer == null) parentRenderer = parent.gameObject.AddComponent<MeshRenderer>();
        parentRenderer.sharedMaterial = sharedMaterial;

        // 保存网格到资源(可选,防止丢失)
        AssetDatabase.CreateAsset(combinedMesh, $"Assets/Combined_MRT_Mesh.asset");
        AssetDatabase.SaveAssets();

        Debug.Log("网格合并完成!");
    }
}

使用步骤:

  1. 在Unity编辑器中创建一个新的C#脚本,把上面的代码粘贴进去
  2. 回到编辑器,顶部菜单栏会出现Tools/Combine Mass Meshes选项
  3. 选中场景中的default对象,点击按钮开始合并

注意:如果子物体有不同材质,脚本需要修改为按材质分组合并(生成多个子网格),但如果你需要单个网格,建议先统一所有子物体的材质。

二、Unity内置工具优化方案

如果你不想写脚本,可以试试用Unity的EditorUtility.CollectDeepHierarchy来批量选择所有MeshPart,然后用内置的合并功能:

  • 选中default对象,右键选择Select Children(或展开层级后全选)
  • 打开Window > Modeling > Mesh Inspector
  • 在Mesh Inspector中点击Combine Meshes,选择Combine into one

不过这种方式在子物体数量极多时(比如上千个),可能会出现编辑器卡顿,但比Mesh Combine Wizard更稳定。

三、Asset Store替代工具

如果自定义脚本太麻烦,可以试试Asset Store上的Mesh Baker,它专门针对大量网格合并做了优化,支持按材质、批次合并,处理医疗切片模型这类场景非常高效,而且有可视化界面操作,比Mesh Combine Wizard的上限高很多。

最后提醒:合并前一定要备份原始模型,避免操作失误丢失数据!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:26:31