Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct here to familiarize yourself with the rules and how to post constructively.

  2. Unity 2022.1 is now available as the latest Tech release.
    Dismiss Notice
  3. Improve your project's performance with our new guide on profiling in Unity.
    Dismiss Notice

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:
    27
    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.  
     
unityunity