Нема описа
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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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 enum GridPaletteType
  12. {
  13. Rectangle,
  14. HexagonalPointTop,
  15. HexagonalFlatTop,
  16. Isometric,
  17. IsometricZAsY,
  18. };
  19. internal static readonly Vector3 defaultSortAxis = new Vector3(0f, 0f, 1f);
  20. internal static GridLayout.CellLayout GetCellLayoutFromGridPaletteType(GridPaletteType paletteType)
  21. {
  22. switch (paletteType)
  23. {
  24. case GridPaletteType.HexagonalPointTop:
  25. case GridPaletteType.HexagonalFlatTop:
  26. {
  27. return GridLayout.CellLayout.Hexagon;
  28. }
  29. case GridPaletteType.Isometric:
  30. {
  31. return GridLayout.CellLayout.Isometric;
  32. }
  33. case GridPaletteType.IsometricZAsY:
  34. {
  35. return GridLayout.CellLayout.IsometricZAsY;
  36. }
  37. }
  38. return GridLayout.CellLayout.Rectangle;
  39. }
  40. internal static RectInt GetBounds(GameObject palette)
  41. {
  42. if (palette == null)
  43. return new RectInt();
  44. Vector2Int min = new Vector2Int(int.MaxValue, int.MaxValue);
  45. Vector2Int max = new Vector2Int(int.MinValue, int.MinValue);
  46. foreach (var tilemap in palette.GetComponentsInChildren<Tilemap>())
  47. {
  48. Vector3Int p1 = tilemap.editorPreviewOrigin;
  49. Vector3Int p2 = p1 + tilemap.editorPreviewSize;
  50. Vector2Int tilemapMin = new Vector2Int(Mathf.Min(p1.x, p2.x), Mathf.Min(p1.y, p2.y));
  51. Vector2Int tilemapMax = new Vector2Int(Mathf.Max(p1.x, p2.x), Mathf.Max(p1.y, p2.y));
  52. min = new Vector2Int(Mathf.Min(min.x, tilemapMin.x), Mathf.Min(min.y, tilemapMin.y));
  53. max = new Vector2Int(Mathf.Max(max.x, tilemapMax.x), Mathf.Max(max.y, tilemapMax.y));
  54. }
  55. return GridEditorUtility.GetMarqueeRect(min, max);
  56. }
  57. /// <summary>
  58. /// Creates a Palette Asset at the current selected folder path. This will show a popup allowing you to choose
  59. /// a different folder path for saving the Palette Asset if required.
  60. /// </summary>
  61. /// <param name="name">Name of the Palette Asset.</param>
  62. /// <param name="layout">Grid Layout of the Palette Asset.</param>
  63. /// <param name="cellSizing">Cell Sizing of the Palette Asset.</param>
  64. /// <param name="cellSize">Cell Size of the Palette Asset.</param>
  65. /// <param name="swizzle">Cell Swizzle of the Palette.</param>
  66. /// <returns>The created Palette Asset if successful.</returns>
  67. public static GameObject CreateNewPaletteAtCurrentFolder(string name, GridLayout.CellLayout layout, GridPalette.CellSizing cellSizing, Vector3 cellSize, GridLayout.CellSwizzle swizzle)
  68. {
  69. return CreateNewPaletteAtCurrentFolder(name, layout, cellSizing, cellSize, swizzle
  70. , TransparencySortMode.Default, defaultSortAxis);
  71. }
  72. /// <summary>
  73. /// Creates a Palette Asset at the current selected folder path. This will show a popup allowing you to choose
  74. /// a different folder path for saving the Palette Asset if required.
  75. /// </summary>
  76. /// <param name="name">Name of the Palette Asset.</param>
  77. /// <param name="layout">Grid Layout of the Palette Asset.</param>
  78. /// <param name="cellSizing">Cell Sizing of the Palette Asset.</param>
  79. /// <param name="cellSize">Cell Size of the Palette Asset.</param>
  80. /// <param name="swizzle">Cell Swizzle of the Palette.</param>
  81. /// <param name="sortMode">Transparency Sort Mode for the Palette</param>
  82. /// <param name="sortAxis">Transparency Sort Axis for the Palette</param>
  83. /// <returns>The created Palette Asset if successful.</returns>
  84. public static GameObject CreateNewPaletteAtCurrentFolder(string name
  85. , GridLayout.CellLayout layout
  86. , GridPalette.CellSizing cellSizing
  87. , Vector3 cellSize
  88. , GridLayout.CellSwizzle swizzle
  89. , TransparencySortMode sortMode
  90. , Vector3 sortAxis)
  91. {
  92. string defaultPath = ProjectBrowser.s_LastInteractedProjectBrowser ? ProjectBrowser.s_LastInteractedProjectBrowser.GetActiveFolderPath() : "Assets";
  93. string folderPath = EditorUtility.SaveFolderPanel("Create palette into folder ", defaultPath, "");
  94. folderPath = FileUtil.GetProjectRelativePath(folderPath);
  95. if (string.IsNullOrEmpty(folderPath))
  96. return null;
  97. return CreateNewPalette(folderPath, name, layout, cellSizing, cellSize, swizzle, sortMode, sortAxis);
  98. }
  99. /// <summary>
  100. /// Creates a Palette Asset at the given folder path.
  101. /// </summary>
  102. /// <param name="folderPath">Folder Path of the Palette Asset.</param>
  103. /// <param name="name">Name of the Palette Asset.</param>
  104. /// <param name="layout">Grid Layout of the Palette Asset.</param>
  105. /// <param name="cellSizing">Cell Sizing of the Palette Asset.</param>
  106. /// <param name="cellSize">Cell Size of the Palette Asset.</param>
  107. /// <param name="swizzle">Cell Swizzle of the Palette.</param>
  108. /// <returns>The created Palette Asset if successful.</returns>
  109. public static GameObject CreateNewPalette(string folderPath
  110. , string name
  111. , GridLayout.CellLayout layout
  112. , GridPalette.CellSizing cellSizing
  113. , Vector3 cellSize
  114. , GridLayout.CellSwizzle swizzle)
  115. {
  116. return CreateNewPalette(folderPath, name, layout, cellSizing, cellSize, swizzle,
  117. TransparencySortMode.Default, defaultSortAxis);
  118. }
  119. /// <summary>
  120. /// Creates a Palette Asset at the given folder path.
  121. /// </summary>
  122. /// <param name="folderPath">Folder Path of the Palette Asset.</param>
  123. /// <param name="name">Name of the Palette Asset.</param>
  124. /// <param name="layout">Grid Layout of the Palette Asset.</param>
  125. /// <param name="cellSizing">Cell Sizing of the Palette Asset.</param>
  126. /// <param name="cellSize">Cell Size of the Palette Asset.</param>
  127. /// <param name="swizzle">Cell Swizzle of the Palette.</param>
  128. /// <param name="sortMode">Transparency Sort Mode for the Palette</param>
  129. /// <param name="sortAxis">Transparency Sort Axis for the Palette</param>
  130. /// <returns>The created Palette Asset if successful.</returns>
  131. public static GameObject CreateNewPalette(string folderPath
  132. , string name
  133. , GridLayout.CellLayout layout
  134. , GridPalette.CellSizing cellSizing
  135. , Vector3 cellSize
  136. , GridLayout.CellSwizzle swizzle
  137. , TransparencySortMode sortMode
  138. , Vector3 sortAxis)
  139. {
  140. GameObject temporaryGO = new GameObject(name);
  141. Grid grid = temporaryGO.AddComponent<Grid>();
  142. // We set size to kEpsilon to mark this as new uninitialized palette
  143. // Nice default size can be decided when first asset is dragged in
  144. grid.cellSize = cellSize;
  145. grid.cellLayout = layout;
  146. grid.cellSwizzle = swizzle;
  147. CreateNewLayer(temporaryGO, "Layer1", layout);
  148. string path = AssetDatabase.GenerateUniqueAssetPath(folderPath + "/" + name + ".prefab");
  149. Object prefab = PrefabUtility.SaveAsPrefabAssetAndConnect(temporaryGO, path, InteractionMode.AutomatedAction);
  150. GridPalette palette = CreateGridPalette(cellSizing, sortMode, sortAxis);
  151. AssetDatabase.AddObjectToAsset(palette, prefab);
  152. PrefabUtility.ApplyPrefabInstance(temporaryGO, InteractionMode.AutomatedAction);
  153. AssetDatabase.Refresh();
  154. Object.DestroyImmediate(temporaryGO);
  155. return AssetDatabase.LoadAssetAtPath<GameObject>(path);
  156. }
  157. private static GameObject CreateNewLayer(GameObject paletteGO, string name, GridLayout.CellLayout layout)
  158. {
  159. GameObject newLayerGO = new GameObject(name);
  160. var tilemap = newLayerGO.AddComponent<Tilemap>();
  161. var renderer = newLayerGO.AddComponent<TilemapRenderer>();
  162. newLayerGO.transform.parent = paletteGO.transform;
  163. newLayerGO.layer = paletteGO.layer;
  164. // Set defaults for certain layouts
  165. switch (layout)
  166. {
  167. case GridLayout.CellLayout.Hexagon:
  168. {
  169. tilemap.tileAnchor = Vector3.zero;
  170. break;
  171. }
  172. case GridLayout.CellLayout.Isometric:
  173. {
  174. renderer.sortOrder = TilemapRenderer.SortOrder.TopRight;
  175. break;
  176. }
  177. case GridLayout.CellLayout.IsometricZAsY:
  178. {
  179. renderer.sortOrder = TilemapRenderer.SortOrder.TopRight;
  180. renderer.mode = TilemapRenderer.Mode.Individual;
  181. break;
  182. }
  183. }
  184. return newLayerGO;
  185. }
  186. internal static GridPalette GetGridPaletteFromPaletteAsset(Object palette)
  187. {
  188. string assetPath = AssetDatabase.GetAssetPath(palette);
  189. GridPalette paletteAsset = AssetDatabase.LoadAssetAtPath<GridPalette>(assetPath);
  190. return paletteAsset;
  191. }
  192. internal static GridPalette CreateGridPalette(GridPalette.CellSizing cellSizing)
  193. {
  194. return CreateGridPalette(cellSizing, TransparencySortMode.Default, defaultSortAxis);
  195. }
  196. internal static GridPalette CreateGridPalette(GridPalette.CellSizing cellSizing
  197. , TransparencySortMode sortMode
  198. , Vector3 sortAxis
  199. )
  200. {
  201. var palette = ScriptableObject.CreateInstance<GridPalette>();
  202. palette.name = "Palette Settings";
  203. palette.cellSizing = cellSizing;
  204. palette.transparencySortMode = sortMode;
  205. palette.transparencySortAxis = sortAxis;
  206. return palette;
  207. }
  208. internal static Vector3 CalculateAutoCellSize(Grid grid, Vector3 defaultValue)
  209. {
  210. Tilemap[] tilemaps = grid.GetComponentsInChildren<Tilemap>();
  211. Sprite[] sprites = null;
  212. var maxSize = Vector2.negativeInfinity;
  213. var minSize = Vector2.positiveInfinity;
  214. // Get minimum and maximum sizes for Sprites
  215. foreach (var tilemap in tilemaps)
  216. {
  217. var spriteCount = tilemap.GetUsedSpritesCount();
  218. if (sprites == null || sprites.Length < spriteCount)
  219. sprites = new Sprite[spriteCount];
  220. tilemap.GetUsedSpritesNonAlloc(sprites);
  221. for (int i = 0; i < spriteCount; ++i)
  222. {
  223. Sprite sprite = sprites[i];
  224. if (sprite != null)
  225. {
  226. var cellSize = new Vector3(sprite.rect.width, sprite.rect.height, 0f) / sprite.pixelsPerUnit;
  227. if (tilemap.cellSwizzle == GridLayout.CellSwizzle.YXZ)
  228. {
  229. var swap = cellSize.x;
  230. cellSize.x = cellSize.y;
  231. cellSize.y = swap;
  232. }
  233. minSize.x = Mathf.Min(cellSize.x, minSize.x);
  234. minSize.y = Mathf.Min(cellSize.y, minSize.y);
  235. maxSize.x = Mathf.Max(cellSize.x, maxSize.x);
  236. maxSize.y = Mathf.Max(cellSize.y, maxSize.y);
  237. }
  238. }
  239. }
  240. // Validate that Sprites are in multiples of sizes
  241. foreach (var tilemap in tilemaps)
  242. {
  243. var spriteCount = tilemap.GetUsedSpritesCount();
  244. if (sprites == null || sprites.Length < spriteCount)
  245. sprites = new Sprite[spriteCount];
  246. tilemap.GetUsedSpritesNonAlloc(sprites);
  247. for (int i = 0; i < spriteCount; ++i)
  248. {
  249. Sprite sprite = sprites[i];
  250. if (sprite != null)
  251. {
  252. var cellSize = new Vector3(sprite.rect.width, sprite.rect.height, 0f) / sprite.pixelsPerUnit;
  253. if (tilemap.cellSwizzle == GridLayout.CellSwizzle.YXZ)
  254. {
  255. var swap = cellSize.x;
  256. cellSize.x = cellSize.y;
  257. cellSize.y = swap;
  258. }
  259. // Return maximum size if sprites are not multiples of the smallest size
  260. if (cellSize.x % minSize.x > 0)
  261. return maxSize.x * maxSize.y <= 0f ? defaultValue : new Vector3(maxSize.x, maxSize.y, 0f);
  262. if (cellSize.y % minSize.y > 0)
  263. return maxSize.x * maxSize.y <= 0f ? defaultValue : new Vector3(maxSize.x, maxSize.y, 0f);
  264. }
  265. }
  266. }
  267. return minSize.x * minSize.y <= 0f || minSize == Vector2.positiveInfinity ? defaultValue : new Vector3(minSize.x, minSize.y, 0f);
  268. }
  269. }
  270. }