private void PrepareMap()
        {
            this.map = new MeshData[this.tileSystem.RowCount, this.tileSystem.ColumnCount];

            for (int row = 0; row < this.tileSystem.RowCount; ++row)
            {
                for (int column = 0; column < this.tileSystem.ColumnCount; ++column)
                {
                    TileData tile = this.tileSystem.GetTile(row, column);
                    if (tile == null || tile.gameObject == null || tile.brush == null || !tile.brush.Static)
                    {
                        continue;
                    }

                    MeshFilter[] filters = tile.gameObject.GetComponentsInChildren <MeshFilter>();
                    if (filters.Length == 0)
                    {
                        continue;
                    }

                    // Merge tile meshes into a single mesh
                    MeshData meshData = new MeshData();
                    this.meshProcessor.Mount(meshData);

                    foreach (MeshFilter filter in filters)
                    {
                        MeshRenderer renderer = filter.GetComponent <MeshRenderer>();
                        if (renderer == null || !renderer.enabled || filter.sharedMesh == null)
                        {
                            continue;
                        }

                        this.meshProcessor.AppendMesh(filter.transform, filter, renderer);

                        // Renderer and filter components are no longer needed
                        Object.DestroyImmediate(renderer);
                        Object.DestroyImmediate(filter);
                    }

                    // Strip empty tile!
                    if (this.tileSystem.StripCombinedEmptyObjects)
                    {
                        StrippingUtility.StripEmptyGameObject(tile.gameObject.transform);
                    }

                    this.meshProcessor.Apply();
                    if (!meshData.IsEmpty)
                    {
                        meshData.Smooth = tile.brush.Smooth;
                        meshData.CopyOriginalNormals();

                        this.map[row, column] = meshData;
                    }
                }

                this.ReportProgress();
            }
        }
        private void DestroyGeneratedProceduralMeshes(TileSystem system)
        {
            foreach (var proceduralMesh in system.GetComponentsInChildren <ProceduralMesh>())
            {
                var transform = proceduralMesh.transform;

                Object.DestroyImmediate(transform.GetComponent <MeshFilter>());
                Object.DestroyImmediate(transform.GetComponent <MeshRenderer>());

                Object.DestroyImmediate(proceduralMesh.mesh);

                Object.DestroyImmediate(proceduralMesh);

                StrippingUtility.StripEmptyGameObject(transform);
            }
        }
    /// <summary>
    /// Upgrade tile system from v1.0.0-v1.0.8 to v2.0.0.
    /// </summary>
    /// <remarks>
    /// <para>Replicates upgrade process that was included in v1.0.9+ but converts straight
    /// to v2.0.0 instead of v1.0.9.</para>
    /// </remarks>
    /// <param name="v1">Old tile system.</param>
    public static void UpgradeTileSystemA(MonoBehaviour v1)
    {
        RtsUpgradedBrushMap map = RtsBrushUpgradeUtility.BrushMappings;

        EditorUtility.DisplayProgressBar("Upgrade Tile System", "Initializing new data structure...", 0.0f);
        try {
            PropertyInfo piTileData_hasGameObject = typeof(TileData).GetProperty("HasGameObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            Vector3 tileSize = (Vector3)_fiTileSystem_tileSize.GetValue(v1);
            int     rows     = (int)_fiTileSystem_rows.GetValue(v1);
            int     columns  = (int)_fiTileSystem_columns.GetValue(v1);

            // Create v2.x tile system.
            TileSystem v2 = v1.gameObject.AddComponent <TileSystem>();
            v2.CreateSystem(tileSize.x, tileSize.y, tileSize.z, rows, columns, 30, 30);
            CopyProperties(v1, v2);

            // Assume value that was consistent with original default settings
            v2.applyRuntimeStripping = true;
            v2.StrippingPreset       = StrippingPreset.NoStripping;
            v2.BeginBulkEdit();

            Component[] instanceComponents = v1.GetComponentsInChildren(_tyTileInstance, true);

            float task      = 0.0f;
            float taskCount = instanceComponents.Length;
            float taskRatio = 1.0f / taskCount;

            TileData tile = new TileData();

            // Retrieve all tile instance components
            foreach (MonoBehaviour instance in instanceComponents)
            {
                EditorUtility.DisplayProgressBar("Upgrade Tile System", "Processing tile data...", (task++) * taskRatio);

                int row    = (int)_fiTileInstance_row.GetValue(instance);
                int column = (int)_fiTileInstance_column.GetValue(instance);

                tile.Clear();

                // Create and assign tile data
                tile.brush           = map.Lookup((Object)_piTileInstance_brush.GetValue(instance, null));
                tile.orientationMask = (byte)OrientationUtility.MaskFromName((string)_fiTileInstance_orientationName.GetValue(instance));
                tile.variationIndex  = (byte)(int)_fiTileInstance_variationIndex.GetValue(instance);
                tile.Empty           = false;
                tile.gameObject      = instance.gameObject;
                piTileData_hasGameObject.SetValue(tile, true, null);

                v2.SetTileFrom(row, column, tile);

                Chunk chunk = v2.GetChunkFromTileIndex(row, column);
                ForceRepaintForAtlasTiles(v2.GetTile(row, column), chunk);
                if (instance == null)
                {
                    continue;
                }

                // Cleanup original tile instance?
                if (!StrippingUtility.StripEmptyGameObject(instance.transform))
                {
                    // Reparent game object to its shiny new chunk!
                    instance.gameObject.transform.parent = chunk.transform;
                }

                // Destroy unwanted tile instance component
                Object.DestroyImmediate(instance);
            }

            int count = v2.EndBulkEdit();
            RemoveTileSystem(v1);

            if (count > 0)
            {
                Debug.Log(string.Format("Upgrade of tile system '{0}' completed and {1} tile(s) were force refreshed.", v2.name, count));
            }
            else
            {
                Debug.Log(string.Format("Upgrade of tile system '{0}' completed.", v2.name));
            }
        }
        finally {
            EditorUtility.ClearProgressBar();
        }
    }