Search Unity

Feedback Fed up of poor tile placement in tile palette by Unity ? Here's a fix!

Discussion in '2D' started by aybeone, May 30, 2019.

  1. aybeone

    aybeone

    Joined:
    May 24, 2015
    Posts:
    107
    So Unity makes working with 2D tiles a real pain, it just places them all next to each other, making it very difficult to spot and pick ones that are elevated:

    2019-05-30_00-57-00.png

    I've wrote a small tool that re-distributes them :)!

    Unity_2019-05-30_00-57-10.png

    Now it's easier to identify and pick them!

    2019-05-30_00-57-21.png

    Code:

    Code (CSharp):
    1. using System;
    2. using System.Linq;
    3. using UnityEditor;
    4. using UnityEngine;
    5. using UnityEngine.Tilemaps;
    6.  
    7. namespace z
    8. {
    9.     internal sealed class TilePaletteAdjuster : EditorWindow
    10.     {
    11.         [SerializeField]
    12.         private int Extent = 10;
    13.  
    14.         [SerializeField]
    15.         private GameObject Prefab;
    16.  
    17.         [SerializeField]
    18.         private bool Square = true;
    19.  
    20.         [SerializeField]
    21.         private int Stride = 3;
    22.  
    23.         private Tilemap Tilemap => Prefab != null ? Prefab.GetComponentInChildren<Tilemap>() : null;
    24.  
    25.         [MenuItem("z/Tile Palette Adjuster")]
    26.         private static void ShowWindow()
    27.         {
    28.             var window = GetWindow<TilePaletteAdjuster>(true, "Tile Palette Adjuster", true);
    29.             window.minSize = window.maxSize = new Vector2(333.0f, 111.0f);
    30.         }
    31.  
    32.         private void OnGUI()
    33.         {
    34.             Prefab = EditorGUILayout.ObjectField(new GUIContent("Prefab", "The tile palette to adjust."),
    35.                 Prefab, typeof(GameObject), false) as GameObject;
    36.  
    37.             using (new EditorGUI.DisabledGroupScope(Square))
    38.             {
    39.                 Extent = EditorGUILayout.IntSlider(
    40.                     new GUIContent("Extent", "The extend to distribute tiles on."), Extent, 1, 20);
    41.             }
    42.  
    43.             Stride = EditorGUILayout.IntSlider(
    44.                 new GUIContent("Stride", "The stride between each tiles."), Stride, 1, 10);
    45.  
    46.             Square = EditorGUILayout.Toggle(
    47.                 new GUIContent("Square", "Distribute tiles in a square fashion."), Square);
    48.  
    49.             EditorGUILayout.Space();
    50.  
    51.             var disabled = Prefab == null ||
    52.                            PrefabUtility.GetPrefabAssetType(Prefab) != PrefabAssetType.Regular ||
    53.                            Tilemap == null;
    54.  
    55.             using (new EditorGUILayout.HorizontalScope())
    56.             using (new EditorGUI.DisabledGroupScope(disabled))
    57.             {
    58.                 GUILayout.FlexibleSpace();
    59.  
    60.                 if (GUILayout.Button("Adjust", GUILayout.Width(75.0f)))
    61.                     Adjust();
    62.             }
    63.         }
    64.  
    65.         private void Adjust()
    66.         {
    67.             var tilemap = Tilemap;
    68.             if (tilemap is null)
    69.                 throw new ArgumentNullException(nameof(tilemap));
    70.  
    71.             var block = tilemap.GetTilesBlock(tilemap.cellBounds);
    72.             var tiles = block.Where(s => s != null).OrderBy(s => s.name).ToArray();
    73.             var ceil = (int) Mathf.Ceil(Mathf.Sqrt(tiles.Length));
    74.             var w = Square ? ceil : Extent;
    75.             var h = Square ? ceil : tiles.Length / Extent + (tiles.Length % Extent == 0 ? 0 : 1);
    76.             var z = tilemap.cellBounds.size.z;
    77.  
    78.             var array = new TileBase[w * Stride * h * Stride];
    79.             var index = 0;
    80.  
    81.             foreach (var tile in tiles)
    82.             {
    83.                 var x = index % w * Stride;
    84.                 var y = index / w * Stride;
    85.                 var i = y * w * Stride + x;
    86.                 array[i] = tile;
    87.                 index++;
    88.             }
    89.  
    90.             // if we save asset we lose undo, but then preview in Tile Palette fails, this hack allows both
    91.             Selection.activeObject = Prefab;
    92.  
    93.             Undo.RecordObject(tilemap, "Adjust Tile Palette");
    94.  
    95.             tilemap.ClearAllTiles();
    96.             tilemap.size = new Vector3Int(w * Stride, h * Stride, z);
    97.             tilemap.SetTilesBlock(tilemap.cellBounds, array);
    98.  
    99.             PrefabUtility.RecordPrefabInstancePropertyModifications(tilemap);
    100.             EditorUtility.SetDirty(Prefab);
    101.         }
    102.     }
    103. }
    Hope that'll ring some bell at Unity ...

    Comment and share your improvements!
     
    AdamOfEternia likes this.
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    I think this is nice because you can have both spaced out tiles and adjacent tiles, but to get the visual results in your screenshot, you could increase the gap value of the palette asset's grid component I believe.
     
    aybeone likes this.
  3. aybeone

    aybeone

    Joined:
    May 24, 2015
    Posts:
    107
    haven't thought about that, really clever!

    2019-05-30_22-59-10.png

    it's even more clear as on where the content is supposed to sit in the tile.

    Thanks :)
     
    AdamOfEternia and LiterallyJeff like this.
  4. AdamOfEternia

    AdamOfEternia

    Joined:
    Dec 21, 2013
    Posts:
    1
    Literally stumbled across this today after my tile frustration was boiling over... an absolute god-send - can't thank you enough!!!! :)