Açıklama Yok
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GridPaletteUtility.cs 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. Sprite[] sprites = null;
  184. var maxSize = Vector2.negativeInfinity;
  185. var minSize = Vector2.positiveInfinity;
  186. // Get minimum and maximum sizes for Sprites
  187. foreach (var tilemap in tilemaps)
  188. {
  189. var spriteCount = tilemap.GetUsedSpritesCount();
  190. if (sprites == null || sprites.Length < spriteCount)
  191. sprites = new Sprite[spriteCount];
  192. tilemap.GetUsedSpritesNonAlloc(sprites);
  193. for (int i = 0; i < spriteCount; ++i)
  194. {
  195. Sprite sprite = sprites[i];
  196. if (sprite != null)
  197. {
  198. var cellSize = new Vector3(sprite.rect.width, sprite.rect.height, 0f) / sprite.pixelsPerUnit;
  199. if (tilemap.cellSwizzle == GridLayout.CellSwizzle.YXZ)
  200. {
  201. var swap = cellSize.x;
  202. cellSize.x = cellSize.y;
  203. cellSize.y = swap;
  204. }
  205. minSize.x = Mathf.Min(cellSize.x, minSize.x);
  206. minSize.y = Mathf.Min(cellSize.y, minSize.y);
  207. maxSize.x = Mathf.Max(cellSize.x, maxSize.x);
  208. maxSize.y = Mathf.Max(cellSize.y, maxSize.y);
  209. }
  210. }
  211. }
  212. // Validate that Sprites are in multiples of sizes
  213. foreach (var tilemap in tilemaps)
  214. {
  215. var spriteCount = tilemap.GetUsedSpritesCount();
  216. if (sprites == null || sprites.Length < spriteCount)
  217. sprites = new Sprite[spriteCount];
  218. tilemap.GetUsedSpritesNonAlloc(sprites);
  219. for (int i = 0; i < spriteCount; ++i)
  220. {
  221. Sprite sprite = sprites[i];
  222. if (sprite != null)
  223. {
  224. var cellSize = new Vector3(sprite.rect.width, sprite.rect.height, 0f) / sprite.pixelsPerUnit;
  225. if (tilemap.cellSwizzle == GridLayout.CellSwizzle.YXZ)
  226. {
  227. var swap = cellSize.x;
  228. cellSize.x = cellSize.y;
  229. cellSize.y = swap;
  230. }
  231. // Return maximum size if sprites are not multiples of the smallest size
  232. if (cellSize.x % minSize.x > 0)
  233. return maxSize.x * maxSize.y <= 0f ? defaultValue : new Vector3(maxSize.x, maxSize.y, 0f);
  234. if (cellSize.y % minSize.y > 0)
  235. return maxSize.x * maxSize.y <= 0f ? defaultValue : new Vector3(maxSize.x, maxSize.y, 0f);
  236. }
  237. }
  238. }
  239. return minSize.x * minSize.y <= 0f || minSize == Vector2.positiveInfinity ? defaultValue : new Vector3(minSize.x, minSize.y, 0f);
  240. }
  241. }
  242. }