在运行时在Unity中合并网格

时间:2018-08-12 00:30:20

标签: unity3d mesh

我正在尝试在运行时将“座椅预制件”组合到单个网格中,以节省一些绘制调用。

我的座位包含2个MeshFilter,一个底部和一个顶部(=座位,图片上的红色),并带有2种不同的材质。我的座位是从已启用读/写功能的导入FBX创建的。

如果重要的话,我正在使用池:我产生500个席位,然后从池中选择250个以创建我的展位,然后我将它们合并,释放合并的席位并再利用它们以合并另一个席位。

这是某些座位上出现的问题(不是所有座位,只有第5和6座,因此可能与某些汇总问题相关联?多次重复使用相同的网格),某些座位的“顶部”“链接”在一起 enter image description here

这是我使用的功能:

  List<CombineInstance> baseList = new List<CombineInstance>();
        List<CombineInstance> topList = new List<CombineInstance>();

        Material materialTop = null;
        Material materialBase = null;

        //Loop through the array with trees
        for (int i = 0; i < seats.Count; i++)
        {
            GameObject currentSeat = seats[i];


            //Get all meshfilters from this seat, true to also find deactivated children
            MeshFilter[] meshFilters = currentSeat.GetComponentsInChildren<MeshFilter>(true);


            //Loop through all children
            for (int j = 0; j < meshFilters.Length; j++)
            {
                MeshFilter meshFilter = meshFilters[j];

                CombineInstance combine = new CombineInstance();

                //Is it top or base?
                MeshRenderer meshRender = meshFilter.GetComponent<MeshRenderer>();

                string materialName = meshRender.gameObject.name;

                if (materialName.Contains("top"))
                {
                    combine.mesh = meshFilter.mesh;
                    combine.transform = meshFilter.transform.localToWorldMatrix;

                    //Add it to the list of leaf mesh data
                    topList.Add(combine);

                    if (materialTop == null) materialTop = meshRender.material;
                }
                else if (materialName.Contains("base"))
                {
                    combine.mesh = meshFilter.mesh;
                    combine.transform = meshFilter.transform.localToWorldMatrix;

                    //Add it to the list of wood mesh data
                    baseList.Add(combine);

                    if (materialBase == null) materialBase = meshRender.material;
                }
            }


            //Deactivate the seat the pool 
            GameController.This.Prefabs.DestroyPooledObject(currentSeat);
        }


        //First we need to combine the bases into one mesh and then the tops into one mesh
        Mesh combinedBaseMesh = new Mesh();
        combinedBaseMesh.CombineMeshes(baseList.ToArray());

        Mesh combinedTopMesh = new Mesh();
        combinedTopMesh.CombineMeshes(topList.ToArray());

        //Create the array that will form the combined mesh
        CombineInstance[] totalMesh = new CombineInstance[2];

        //Add the submeshes in the same order as the material is set in the combined mesh
        totalMesh[0].mesh = combinedBaseMesh;
        totalMesh[0].transform = parent.transform.localToWorldMatrix;
        totalMesh[1].mesh = combinedTopMesh;
        totalMesh[1].transform = parent.transform.localToWorldMatrix;

        //Create the final combined mesh
        Mesh combinedAllMesh = new Mesh();

        //Make sure it's set to false to get 2 separate meshes
        combinedAllMesh.CombineMeshes(totalMesh, false);

        var meshFilterParent = parent.GetComponent<MeshFilter>();
        if (meshFilterParent == null) meshFilterParent = parent.AddComponent<MeshFilter>();
        meshFilterParent.sharedMesh = combinedAllMesh;


        var meshRenderer = parent.GetComponent<MeshRenderer>();
        if (meshRenderer == null) meshRenderer = parent.AddComponent<MeshRenderer>();
        meshRenderer.materials = new
            Material[]
            {
                materialBase,
                materialTop
            };

0 个答案:

没有答案