/// <summary> /// Erase all out-of-bound tiles. /// </summary> /// <param name="system">Tile system.</param> /// <param name="newRows">New number of rows.</param> /// <param name="newColumns">New number of columns.</param> /// <param name="rowOffset">Number of rows of tiles to offset by.</param> /// <param name="columnOffset">Number of columns of tiles to offset by.</param> private void EraseOutOfBoundTiles(TileSystem system, int newRows, int newColumns, int rowOffset, int columnOffset) { if (system.Chunks == null) { return; } rowOffset = -rowOffset; columnOffset = -columnOffset; int offsetEndRow = rowOffset + newRows; int offsetEndColumn = columnOffset + newColumns; system.BeginBulkEdit(); for (int row = 0; row < system.RowCount; ++row) { for (int column = 0; column < system.ColumnCount; ++column) { var tile = system.GetTile(row, column); if (tile == null) { continue; } // Is tile out-of-bounds? if (row < rowOffset || row >= offsetEndRow || column < columnOffset || column >= offsetEndColumn) { system.EraseTile(row, column); system.RefreshSurroundingTiles(row, column); } } } system.EndBulkEdit(); }
public static void BulkEditEnd(this TileSystem map) { map.EndBulkEdit(); }
/// <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(); } }
/// <summary> /// Resize tile system. /// </summary> /// <remarks> /// <para>Progress bar is shown when this method is invoked in-editor, though this progress /// bar is not shown when working in play mode.</para> /// </remarks> /// <param name="system">Tile system.</param> /// <param name="newRows">New number of rows.</param> /// <param name="newColumns">New number of columns.</param> /// <param name="rowOffset">Number of rows of tiles to offset by.</param> /// <param name="columnOffset">Number of columns of tiles to offset by.</param> /// <param name="chunkWidth">New chunk width.</param> /// <param name="chunkHeight">New chunk height.</param> /// <param name="maintainTilePositionsInWorld">Indicates if tile positions should /// be maintained in world space.</param> /// <param name="eraseOutOfBounds">Indicates whether out-of-bound tiles should be /// erased.</param> public void Resize(TileSystem system, int newRows, int newColumns, int rowOffset, int columnOffset, int chunkWidth, int chunkHeight, bool maintainTilePositionsInWorld, bool eraseOutOfBounds) { bool restoreEnableProgressHandler = InternalUtility.EnableProgressHandler; InternalUtility.EnableProgressHandler = Application.isEditor && !Application.isPlaying; try { this.taskCount = system.RowCount + newRows; this.taskProgress = 0f; this.taskIncrement = 1f / this.taskCount; // Erase out-of-bound tiles. if (eraseOutOfBounds) { InternalUtility.ProgressHandler("Rebuilding Tile System", "Erasing out-of-bound tiles.", 0f); this.EraseOutOfBoundTiles(system, newRows, newColumns, rowOffset, columnOffset); } InternalUtility.ProgressHandler("Rebuilding Tile System", "Extracting tiles from chunks.", 0f); TileData[,] map = this.GenerateTileMap(system, newRows, newColumns, rowOffset, columnOffset); this.ReparentTileGameObjectsIntoWorldSpace(map); this.RemoveChunkObjects(system); // Update data structure of tile system. Vector3 cellSize = system.CellSize; system.InitializeSystem(cellSize.x, cellSize.y, cellSize.z, newRows, newColumns, chunkWidth, chunkHeight); // Reposition tile system so that tiles are re-parented correctly. Transform systemTransform = system.transform; Vector3 previousLocalPosition = systemTransform.localPosition; systemTransform.position = system.WorldPositionFromTileIndex(-rowOffset, -columnOffset, false); system.BeginBulkEdit(); // Reparent tile game objects. for (int row = 0; row < system.RowCount; ++row) { this.taskProgress += this.taskIncrement; InternalUtility.ProgressHandler("Rebuilding Tile System", "Creating new chunks.", this.taskProgress); for (int column = 0; column < system.ColumnCount; ++column) { var tile = map[row, column]; if (tile == null || tile.Empty) { continue; } // Mark procedural tiles as dirty. if (tile.Procedural) { tile.Dirty = true; } // Assign tile to tile system. system.SetTile(row, column, tile); var chunk = system.GetChunkFromTileIndex(row, column); chunk.Dirty = true; // Place tile game object into chunk. if (tile.gameObject != null) { tile.gameObject.transform.SetParent(chunk.transform); } } } this.taskProgress += this.taskIncrement; InternalUtility.ProgressHandler("Rebuilding Tile System", "Updating tiles.", this.taskProgress); system.EndBulkEdit(); if (!maintainTilePositionsInWorld) { systemTransform.localPosition = previousLocalPosition; } } finally { InternalUtility.ClearProgress(); InternalUtility.EnableProgressHandler = restoreEnableProgressHandler; } }