Search Unity

Issues Editing Tilemap from Editor Script

Discussion in 'Editor & General Support' started by snarlynarwhal, Jan 17, 2018.

  1. snarlynarwhal

    snarlynarwhal

    Joined:
    Jan 16, 2014
    Posts:
    30
    I am trying to write an editor tool to replace tilemap tiles, but cannot get it to work. It appears to run correctly and everything (I logged everything), but the changes simply do not appear when it finishes. I tried EditorUtility.SetDirty and EditorSceneManager.MarkSceneDirty too and nothing works. Here's the entire script:

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEditor;
    3. using UnityEditor.SceneManagement;
    4. using UnityEngine;
    5. using UnityEngine.SceneManagement;
    6. using UnityEngine.Tilemaps;
    7.  
    8. public class ReplaceTilesTool : EditorWindow {
    9.  
    10.     private List<BaseTile> findTiles = new List<BaseTile>();
    11.     private List<BaseTile> replaceTiles = new List<BaseTile>();
    12.  
    13.     [MenuItem("CONTEXT/Grid/Replace Tiles")]
    14.     public static void ShowRenameSpritesheetWindow() {
    15.         GetWindow<ReplaceTilesTool>(true, "Replace Tiles", true);
    16.     }
    17.  
    18.     private void OnGUI() {
    19.         EditorGUILayout.HelpBox("Replace tiles within a grid.", MessageType.None);
    20.         for (int i = 0, len = findTiles.Count; i < len; i++) {
    21.             EditorGUILayout.BeginHorizontal();
    22.             findTiles[i] = (BaseTile) EditorGUILayout.ObjectField(findTiles[i], typeof(BaseTile), false);
    23.             replaceTiles[i] = (BaseTile) EditorGUILayout.ObjectField(replaceTiles[i], typeof(BaseTile), false);
    24.             if (GUILayout.Button("-")) {
    25.                 findTiles.RemoveAt(i);
    26.                 replaceTiles.RemoveAt(i);
    27.                 break;
    28.             }
    29.             EditorGUILayout.EndHorizontal();
    30.         }
    31.         if (GUILayout.Button("+")) {
    32.             findTiles.Add(null);
    33.             replaceTiles.Add(null);
    34.         }
    35.         if (findTiles.Count > 0 && GUILayout.Button("Find and Replace")) {
    36.             FindAndReplace();
    37.         }
    38.     }
    39.  
    40.     private void FindAndReplace() {
    41.         GameObject activeObject = Selection.activeGameObject;
    42.         if (activeObject == null) {
    43.             Debug.LogError("Cannot run Replace Tiles since no Grid component is selected.");
    44.             return;
    45.         }
    46.         Grid grid = activeObject.GetComponent<Grid>();
    47.         if (grid == null) {
    48.             Debug.LogError("Cannot run Replace Tiles since no Grid component is selected.");
    49.             return;
    50.         }
    51.         Tilemap[] tilemaps = grid.GetComponentsInChildren<Tilemap>();
    52.         for (int i = 0, len = tilemaps.Length; i < len; i++) {
    53.             FindReplaceableTilesInTilemap(tilemaps[i]);
    54.             tilemaps[i].RefreshAllTiles();
    55.             EditorUtility.SetDirty(tilemaps[i]);
    56.         }
    57.         EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
    58.     }
    59.  
    60.     private void FindReplaceableTilesInTilemap(Tilemap tilemap) {
    61.         BoundsInt bounds = tilemap.cellBounds;
    62.         TileBase[] allTiles = tilemap.GetTilesBlock(bounds);
    63.         for (int x = 0; x < bounds.size.x; x++) {
    64.             for (int y = 0; y < bounds.size.y; y++) {
    65.                 TileBase tile = allTiles[x + y * bounds.size.x];
    66.                 if (tile == null) {
    67.                     continue;
    68.                 }
    69.                 HandleReplaceTile(tilemap, tile, new Vector3Int(x, y, 0));
    70.             }
    71.         }
    72.     }
    73.  
    74.     private void HandleReplaceTile(Tilemap tilemap, TileBase tile, Vector3Int position) {
    75.         for (int i = 0, len = findTiles.Count; i < len; i++) {
    76.             if (findTiles[i] == tile) {
    77.                 tilemap.SetTile(position, replaceTiles[i]);
    78.             }
    79.         }
    80.     }
    81. }
    82.