GridPaletteUtility.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. using UnityEngine;
  2. using UnityEngine.Tilemaps;
  3. using Object = UnityEngine.Object;
  4. namespace UnityEditor.Tilemaps
  5. {
  6. /// <summary>
  7. /// Utility Class for creating Palettes
  8. /// </summary>
  9. public static class GridPaletteUtility
  10. {
  11. internal static readonly Vector3 defaultSortAxis = new Vector3(0f, 0f, 1f);
  12. internal static RectInt GetBounds(GameObject palette)
  13. {
  14. if (palette == null)
  15. return new RectInt();
  16. Vector2Int min = new Vector2Int(int.MaxValue, int.MaxValue);
  17. Vector2Int max = new Vector2Int(int.MinValue, int.MinValue);
  18. foreach (var tilemap in palette.GetComponentsInChildren<Tilemap>())
  19. {
  20. Vector3Int p1 = tilemap.editorPreviewOrigin;
  21. Vector3Int p2 = p1 + tilemap.editorPreviewSize;
  22. Vector2Int tilemapMin = new Vector2Int(Mathf.Min(p1.x, p2.x), Mathf.Min(p1.y, p2.y));
  23. Vector2Int tilemapMax = new Vector2Int(Mathf.Max(p1.x, p2.x), Mathf.Max(p1.y, p2.y));
  24. min = new Vector2Int(Mathf.Min(min.x, tilemapMin.x), Mathf.Min(min.y, tilemapMin.y));
  25. max = new Vector2Int(Mathf.Max(max.x, tilemapMax.x), Mathf.Max(max.y, tilemapMax.y));
  26. }
  27. return GridEditorUtility.GetMarqueeRect(min, max);
  28. }
  29. /// <summary>
  30. /// Creates a Palette Asset at the current selected folder path. This will show a popup allowing you to choose
  31. /// a different folder path for saving the Palette Asset if required.
  32. /// </summary>
  33. /// <param name="name">Name of the Palette Asset.</param>
  34. /// <param name="layout">Grid Layout of the Palette Asset.</param>
  35. /// <param name="cellSizing">Cell Sizing of the Palette Asset.</param>
  36. /// <param name="cellSize">Cell Size of the Palette Asset.</param>
  37. /// <param name="swizzle">Cell Swizzle of the Palette.</param>
  38. /// <returns>The created Palette Asset if successful.</returns>
  39. public static GameObject CreateNewPaletteAtCurrentFolder(string name, GridLayout.CellLayout layout, GridPalette.CellSizing cellSizing, Vector3 cellSize, GridLayout.CellSwizzle swizzle)
  40. {
  41. return CreateNewPaletteAtCurrentFolder(name, layout, cellSizing, cellSize, swizzle
  42. , TransparencySortMode.Default, defaultSortAxis);
  43. }
  44. /// <summary>
  45. /// Creates a Palette Asset at the current selected folder path. This will show a popup allowing you to choose
  46. /// a different folder path for saving the Palette Asset if required.
  47. /// </summary>
  48. /// <param name="name">Name of the Palette Asset.</param>
  49. /// <param name="layout">Grid Layout of the Palette Asset.</param>
  50. /// <param name="cellSizing">Cell Sizing of the Palette Asset.</param>
  51. /// <param name="cellSize">Cell Size of the Palette Asset.</param>
  52. /// <param name="swizzle">Cell Swizzle of the Palette.</param>
  53. /// <param name="sortMode">Transparency Sort Mode for the Palette</param>
  54. /// <param name="sortAxis">Transparency Sort Axis for the Palette</param>
  55. /// <returns>The created Palette Asset if successful.</returns>
  56. public static GameObject CreateNewPaletteAtCurrentFolder(string name
  57. , GridLayout.CellLayout layout
  58. , GridPalette.CellSizing cellSizing
  59. , Vector3 cellSize
  60. , GridLayout.CellSwizzle swizzle
  61. , TransparencySortMode sortMode
  62. , Vector3 sortAxis)
  63. {
  64. string defaultPath = ProjectBrowser.s_LastInteractedProjectBrowser ? ProjectBrowser.s_LastInteractedProjectBrowser.GetActiveFolderPath() : "Assets";
  65. string folderPath = EditorUtility.SaveFolderPanel("Create palette into folder ", defaultPath, "");
  66. folderPath = FileUtil.GetProjectRelativePath(folderPath);
  67. if (string.IsNullOrEmpty(folderPath))
  68. return null;
  69. return CreateNewPalette(folderPath, name, layout, cellSizing, cellSize, swizzle, sortMode, sortAxis);
  70. }
  71. /// <summary>
  72. /// Creates a Palette Asset at the given folder path.
  73. /// </summary>
  74. /// <param name="folderPath">Folder Path of the Palette Asset.</param>
  75. /// <param name="name">Name of the Palette Asset.</param>
  76. /// <param name="layout">Grid Layout of the Palette Asset.</param>
  77. /// <param name="cellSizing">Cell Sizing of the Palette Asset.</param>
  78. /// <param name="cellSize">Cell Size of the Palette Asset.</param>
  79. /// <param name="swizzle">Cell Swizzle of the Palette.</param>
  80. /// <returns>The created Palette Asset if successful.</returns>
  81. public static GameObject CreateNewPalette(string folderPath
  82. , string name
  83. , GridLayout.CellLayout layout
  84. , GridPalette.CellSizing cellSizing
  85. , Vector3 cellSize
  86. , GridLayout.CellSwizzle swizzle)
  87. {
  88. return CreateNewPalette(folderPath, name, layout, cellSizing, cellSize, swizzle,
  89. TransparencySortMode.Default, defaultSortAxis);
  90. }
  91. /// <summary>
  92. /// Creates a Palette Asset at the given folder path.
  93. /// </summary>
  94. /// <param name="folderPath">Folder Path of the Palette Asset.</param>
  95. /// <param name="name">Name of the Palette Asset.</param>
  96. /// <param name="layout">Grid Layout of the Palette Asset.</param>
  97. /// <param name="cellSizing">Cell Sizing of the Palette Asset.</param>
  98. /// <param name="cellSize">Cell Size of the Palette Asset.</param>
  99. /// <param name="swizzle">Cell Swizzle of the Palette.</param>
  100. /// <param name="sortMode">Transparency Sort Mode for the Palette</param>
  101. /// <param name="sortAxis">Transparency Sort Axis for the Palette</param>
  102. /// <returns>The created Palette Asset if successful.</returns>
  103. public static GameObject CreateNewPalette(string folderPath
  104. , string name
  105. , GridLayout.CellLayout layout
  106. , GridPalette.CellSizing cellSizing
  107. , Vector3 cellSize
  108. , GridLayout.CellSwizzle swizzle
  109. , TransparencySortMode sortMode
  110. , Vector3 sortAxis)
  111. {
  112. GameObject temporaryGO = new GameObject(name);
  113. Grid grid = temporaryGO.AddComponent<Grid>();
  114. // We set size to kEpsilon to mark this as new uninitialized palette
  115. // Nice default size can be decided when first asset is dragged in
  116. grid.cellSize = cellSize;
  117. grid.cellLayout = layout;
  118. grid.cellSwizzle = swizzle;
  119. CreateNewLayer(temporaryGO, "Layer1", layout);
  120. string path = AssetDatabase.GenerateUniqueAssetPath(folderPath + "/" + name + ".prefab");
  121. Object prefab = PrefabUtility.SaveAsPrefabAssetAndConnect(temporaryGO, path, InteractionMode.AutomatedAction);
  122. GridPalette palette = CreateGridPalette(cellSizing, sortMode, sortAxis);
  123. AssetDatabase.AddObjectToAsset(palette, prefab);
  124. PrefabUtility.ApplyPrefabInstance(temporaryGO, InteractionMode.AutomatedAction);
  125. AssetDatabase.Refresh();
  126. Object.DestroyImmediate(temporaryGO);
  127. return AssetDatabase.LoadAssetAtPath<GameObject>(path);
  128. }
  129. private static GameObject CreateNewLayer(GameObject paletteGO, string name, GridLayout.CellLayout layout)
  130. {
  131. GameObject newLayerGO = new GameObject(name);
  132. var tilemap = newLayerGO.AddComponent<Tilemap>();
  133. var renderer = newLayerGO.AddComponent<TilemapRenderer>();
  134. newLayerGO.transform.parent = paletteGO.transform;
  135. newLayerGO.layer = paletteGO.layer;
  136. // Set defaults for certain layouts
  137. switch (layout)
  138. {
  139. case GridLayout.CellLayout.Hexagon:
  140. {
  141. tilemap.tileAnchor = Vector3.zero;
  142. break;
  143. }
  144. case GridLayout.CellLayout.Isometric:
  145. {
  146. renderer.sortOrder = TilemapRenderer.SortOrder.TopRight;
  147. break;
  148. }
  149. case GridLayout.CellLayout.IsometricZAsY:
  150. {
  151. renderer.sortOrder = TilemapRenderer.SortOrder.TopRight;
  152. renderer.mode = TilemapRenderer.Mode.Individual;
  153. break;
  154. }
  155. }
  156. return newLayerGO;
  157. }
  158. internal static GridPalette GetGridPaletteFromPaletteAsset(Object palette)
  159. {
  160. string assetPath = AssetDatabase.GetAssetPath(palette);
  161. GridPalette paletteAsset = AssetDatabase.LoadAssetAtPath<GridPalette>(assetPath);
  162. return paletteAsset;
  163. }
  164. internal static GridPalette CreateGridPalette(GridPalette.CellSizing cellSizing)
  165. {
  166. return CreateGridPalette(cellSizing, TransparencySortMode.Default, defaultSortAxis);
  167. }
  168. internal static GridPalette CreateGridPalette(GridPalette.CellSizing cellSizing
  169. , TransparencySortMode sortMode
  170. , Vector3 sortAxis
  171. )
  172. {
  173. var palette = ScriptableObject.CreateInstance<GridPalette>();
  174. palette.name = "Palette Settings";
  175. palette.cellSizing = cellSizing;
  176. palette.transparencySortMode = sortMode;
  177. palette.transparencySortAxis = sortAxis;
  178. return palette;
  179. }
  180. internal static Vector3 CalculateAutoCellSize(Grid grid, Vector3 defaultValue)
  181. {
  182. Tilemap[] tilemaps = grid.GetComponentsInChildren<Tilemap>();
  183. foreach (var tilemap in tilemaps)
  184. {
  185. foreach (var position in tilemap.cellBounds.allPositionsWithin)
  186. {
  187. Sprite sprite = tilemap.GetSprite(position);
  188. if (sprite != null)
  189. {
  190. var cellSize = new Vector3(sprite.rect.width, sprite.rect.height, 0f) / sprite.pixelsPerUnit;
  191. if (tilemap.cellSwizzle == GridLayout.CellSwizzle.YXZ)
  192. {
  193. var swap = cellSize.x;
  194. cellSize.x = cellSize.y;
  195. cellSize.y = swap;
  196. }
  197. return cellSize;
  198. }
  199. }
  200. }
  201. return defaultValue;
  202. }
  203. }
  204. }