Exemplo n.º 1
0
        static int GetExistingRenderBatch(List <RenderBatchData> renderBatches, Material mat, MeshRenderer ren, int submeshIndex)
        {
            for (int i = 0; i < renderBatches.Count; i++)
            {
                RenderBatchData data = renderBatches[i];
                if (data.Material == mat &&
                    data.SubmeshIndex == submeshIndex &&
                    data.ShadowMode == ren.shadowCastingMode &&
                    data.ReceiveShadows == ren.receiveShadows)
                {
                    return(i);
                }
            }

            return(-1);
        }
Exemplo n.º 2
0
        public static void Combine(List <MeshRenderer> renderers, RendererDisposeMethod disposeMethod, string newObjectName)
        {
            int renderersCount = renderers.Count;

            List <RenderBatchData> renderBatches = new List <RenderBatchData>();

            // Build render batches for all unique material + submeshIndex combinations
            for (int i = 0; i < renderersCount; i++)
            {
                MeshRenderer meshRenderer = renderers[i];

                if (meshRenderer == null)
                {
                    continue;
                }

                MeshFilter meshFilter = meshRenderer.GetComponent <MeshFilter>();

                if (meshFilter == null)
                {
                    continue;
                }

                Mesh mesh = meshFilter.sharedMesh;

                if (mesh == null)
                {
                    continue;
                }

                Transform  t         = meshRenderer.GetComponent <Transform>();
                Material[] materials = meshRenderer.sharedMaterials;

                for (int s = 0; s < mesh.subMeshCount; s++)
                {
                    if (materials[s] == null)
                    {
                        continue;
                    }

                    int batchIndex = GetExistingRenderBatch(renderBatches, materials[s], meshRenderer, s);
                    if (batchIndex >= 0)
                    {
                        renderBatches[batchIndex].MeshesWithTrs.Add(new RenderBatchData.MeshAndTrs(mesh, Matrix4x4.TRS(t.position, t.rotation, t.lossyScale)));
                    }
                    else
                    {
                        RenderBatchData newBatchData = new RenderBatchData();
                        newBatchData.Material       = materials[s];
                        newBatchData.SubmeshIndex   = s;
                        newBatchData.ShadowMode     = meshRenderer.shadowCastingMode;
                        newBatchData.ReceiveShadows = meshRenderer.receiveShadows;
                        newBatchData.MeshesWithTrs.Add(new RenderBatchData.MeshAndTrs(mesh, Matrix4x4.TRS(t.position, t.rotation, t.lossyScale)));

                        renderBatches.Add(newBatchData);
                    }
                }

                switch (disposeMethod)
                {
                case RendererDisposeMethod.DestroyGameObject:
                    if (Application.isPlaying)
                    {
                        GameObject.Destroy(meshRenderer.gameObject);
                    }
                    else
                    {
                        GameObject.DestroyImmediate(meshRenderer.gameObject);
                    }
                    break;

                case RendererDisposeMethod.DestroyRendererAndFilter:
                    if (Application.isPlaying)
                    {
                        GameObject.Destroy(meshRenderer);
                        GameObject.Destroy(meshFilter);
                    }
                    else
                    {
                        GameObject.DestroyImmediate(meshRenderer);
                        GameObject.DestroyImmediate(meshFilter);
                    }
                    break;

                case RendererDisposeMethod.DisableGameObject:
                    meshRenderer.gameObject.SetActive(false);
                    break;

                case RendererDisposeMethod.DisableRenderer:
                    meshRenderer.enabled = false;
                    break;
                }
            }

            // Combine each unique render batch
            for (int i = 0; i < renderBatches.Count; i++)
            {
                RenderBatchData rbd = renderBatches[i];

                Mesh newMesh = new Mesh();
                newMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                CombineInstance[] combineInstances = new CombineInstance[rbd.MeshesWithTrs.Count];

                for (int j = 0; j < rbd.MeshesWithTrs.Count; j++)
                {
                    combineInstances[j].subMeshIndex = rbd.SubmeshIndex;
                    combineInstances[j].mesh         = rbd.MeshesWithTrs[j].Mesh;
                    combineInstances[j].transform    = rbd.MeshesWithTrs[j].Trs;
                }

                // Create mesh
                newMesh.CombineMeshes(combineInstances);
                newMesh.RecalculateBounds();

                // Create the gameObject
                GameObject combinedObject = new GameObject(newObjectName);
                MeshFilter mf             = combinedObject.AddComponent <MeshFilter>();
                mf.sharedMesh = newMesh;
                MeshRenderer mr = combinedObject.AddComponent <MeshRenderer>();
                mr.sharedMaterial    = rbd.Material;
                mr.shadowCastingMode = rbd.ShadowMode;
            }
        }