暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

GameObjectCreation.cs 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. using UnityEngine;
  2. using UnityEngine.Tilemaps;
  3. namespace UnityEditor.Tilemaps
  4. {
  5. static class GameObjectCreation
  6. {
  7. private static class Styles
  8. {
  9. public static readonly string rectangularCreateUndo = L10n.Tr("Create Tilemap");
  10. public static readonly string pointTopHexagonCreateUndo = L10n.Tr("Hexagonal Point Top Tilemap");
  11. public static readonly string flatTopHexagonCreateUndo = L10n.Tr("Hexagonal Flat Top Tilemap");
  12. public static readonly string isometricCreateUndo = L10n.Tr("Isometric Tilemap");
  13. public static readonly string isometricZAsYCreateUndo = L10n.Tr("Isometric Z As Y Tilemap");
  14. public static readonly string copyFromTilePaletteUndo = L10n.Tr("Tilemap with Tile Palette Settings");
  15. public static readonly string modifyExistingGridTitle = L10n.Tr("Modify existing Grid");
  16. public static readonly string modifyExistingGridMessage = L10n.Tr("Creating the Tilemap will modify the existing selected Grid. Continue?");
  17. public static readonly string continueText = L10n.Tr("Continue");
  18. public static readonly string cancelText = L10n.Tr("Cancel");
  19. }
  20. enum TilemapMenuPriority : int
  21. {
  22. Rectangular = 3,
  23. HexagonalFlatTop,
  24. HexagonalPointTop,
  25. Isometric,
  26. IsometricZasY
  27. }
  28. internal static bool showDialog = true;
  29. internal static string[] CreateTilemapTargetsNames = new[]
  30. {
  31. "From Tile Palette"
  32. , "Rectangular Tilemap"
  33. , "Hexagonal Point Top Tilemap"
  34. , "Hexagonal Flat Top Tilemap"
  35. , "Isometric Tilemap"
  36. , "Isometric Z As Y Tilemap"
  37. };
  38. internal static void CreateTilemapTargets(int index)
  39. {
  40. switch (index)
  41. {
  42. case 1:
  43. CreateRectangularTilemap();
  44. break;
  45. case 2:
  46. CreateHexagonalPointTopTilemap();
  47. break;
  48. case 3:
  49. CreateHexagonalFlatTopTilemap();
  50. break;
  51. case 4:
  52. CreateIsometricTilemap();
  53. break;
  54. case 5:
  55. CreateIsometricZAsYTilemap();
  56. break;
  57. case 0:
  58. {
  59. var palette = GridPaintingState.palette;
  60. if (palette == null)
  61. return;
  62. var grid = palette.GetComponentInChildren<Grid>();
  63. if (grid == null)
  64. return;
  65. var newSize = grid.cellSize;
  66. var paletteAsset = GridPaletteUtility.GetGridPaletteFromPaletteAsset(palette);
  67. if (paletteAsset != null && paletteAsset.cellSizing == GridPalette.CellSizing.Automatic)
  68. {
  69. newSize = GridPaletteUtility.CalculateAutoCellSize(grid, grid.cellSize);
  70. }
  71. GameObject newGameObject = null;
  72. switch (grid.cellLayout)
  73. {
  74. case GridLayout.CellLayout.Rectangle:
  75. newGameObject = CreateRectangularTilemapInternal(Styles.copyFromTilePaletteUndo);
  76. break;
  77. case GridLayout.CellLayout.Hexagon:
  78. newGameObject = CreateHexagonalTilemapInternal(grid.cellSwizzle,
  79. Styles.copyFromTilePaletteUndo, newSize);
  80. break;
  81. case GridLayout.CellLayout.Isometric:
  82. newGameObject = CreateIsometricTilemapInternal(GridLayout.CellLayout.Isometric, Styles.copyFromTilePaletteUndo);
  83. break;
  84. case GridLayout.CellLayout.IsometricZAsY:
  85. newGameObject = CreateIsometricTilemapInternal(GridLayout.CellLayout.IsometricZAsY, Styles.copyFromTilePaletteUndo);
  86. break;
  87. }
  88. if (newGameObject == null)
  89. return;
  90. var newGrid = newGameObject.GetComponentInChildren<Grid>();
  91. if (newGrid == null)
  92. return;
  93. var tilemap = palette.GetComponentInChildren<Tilemap>();
  94. var newTilemaps = newGameObject.GetComponentsInChildren<Tilemap>();
  95. // Get last new Tilemap child if there are multiple Tilemaps
  96. var newTilemap = newTilemaps != null && newTilemaps.Length > 0 ? newTilemaps[^1] : null;
  97. var tilemapRenderer = palette.GetComponentInChildren<TilemapRenderer>();
  98. var newTilemapRenderer = newTilemap != null ? newTilemap.GetComponent<TilemapRenderer>() : null;
  99. Undo.RecordObjects(new Object[] {newGrid, newTilemap, newTilemapRenderer}, Styles.copyFromTilePaletteUndo);
  100. if (tilemap != null && newTilemap != null)
  101. {
  102. newTilemap.animationFrameRate = tilemap.animationFrameRate;
  103. newTilemap.color = tilemap.color;
  104. newTilemap.tileAnchor = tilemap.tileAnchor;
  105. newTilemap.orientation = tilemap.orientation;
  106. newTilemap.orientationMatrix = tilemap.orientationMatrix;
  107. }
  108. if (tilemapRenderer != null && newTilemapRenderer != null)
  109. {
  110. newTilemapRenderer.mode = tilemapRenderer.mode;
  111. newTilemapRenderer.chunkSize = tilemapRenderer.chunkSize;
  112. newTilemapRenderer.chunkCullingBounds = tilemapRenderer.chunkCullingBounds;
  113. newTilemapRenderer.detectChunkCullingBounds = tilemapRenderer.detectChunkCullingBounds;
  114. newTilemapRenderer.sortOrder = tilemapRenderer.sortOrder;
  115. newTilemapRenderer.maskInteraction = tilemapRenderer.maskInteraction;
  116. newTilemapRenderer.sortingOrder = tilemapRenderer.sortingOrder;
  117. newTilemapRenderer.sortingLayerID = tilemapRenderer.sortingLayerID;
  118. }
  119. newGrid.cellSwizzle = grid.cellSwizzle;
  120. if (newGrid.cellLayout != GridLayout.CellLayout.Hexagon)
  121. newGrid.cellGap = grid.cellGap;
  122. newGrid.cellSize = newSize;
  123. }
  124. break;
  125. }
  126. }
  127. [MenuItem("GameObject/2D Object/Tilemap/Rectangular", priority = (int)TilemapMenuPriority.Rectangular)]
  128. internal static void CreateRectangularTilemap()
  129. {
  130. CreateRectangularTilemapInternal(Styles.rectangularCreateUndo);
  131. }
  132. [MenuItem("GameObject/2D Object/Tilemap/Hexagonal Flat Top", priority = (int)TilemapMenuPriority.HexagonalFlatTop)]
  133. internal static void CreateHexagonalFlatTopTilemap()
  134. {
  135. CreateHexagonalTilemapInternal(GridLayout.CellSwizzle.YXZ, Styles.flatTopHexagonCreateUndo, new Vector3(0.8659766f, 1, 1));
  136. }
  137. [MenuItem("GameObject/2D Object/Tilemap/Hexagonal Point Top", priority = (int)TilemapMenuPriority.HexagonalPointTop)]
  138. internal static void CreateHexagonalPointTopTilemap()
  139. {
  140. CreateHexagonalTilemapInternal(GridLayout.CellSwizzle.XYZ, Styles.pointTopHexagonCreateUndo, new Vector3(0.8659766f, 1, 1));
  141. }
  142. [MenuItem("GameObject/2D Object/Tilemap/Isometric", priority = (int)TilemapMenuPriority.Isometric)]
  143. internal static void CreateIsometricTilemap()
  144. {
  145. CreateIsometricTilemapInternal(GridLayout.CellLayout.Isometric, Styles.isometricCreateUndo);
  146. }
  147. [MenuItem("GameObject/2D Object/Tilemap/Isometric Z as Y", priority = (int)TilemapMenuPriority.IsometricZasY)]
  148. internal static void CreateIsometricZAsYTilemap()
  149. {
  150. CreateIsometricTilemapInternal(GridLayout.CellLayout.IsometricZAsY, Styles.isometricZAsYCreateUndo);
  151. }
  152. private static GameObject CreateIsometricTilemapInternal(GridLayout.CellLayout isometricLayout, string undoMessage)
  153. {
  154. var valid = FindOrCreateRootGridAndValidate(isometricLayout, false, GridLayout.CellSwizzle.XYZ, true, new Vector3(1.0f, 0.5f, 1.0f), out var root);
  155. if (!valid)
  156. return null;
  157. var uniqueName = GameObjectUtility.GetUniqueNameForSibling(root.transform, "Tilemap");
  158. var tilemapGO = ObjectFactory.CreateGameObject(uniqueName, typeof(Tilemap), typeof(TilemapRenderer));
  159. tilemapGO.transform.SetParent(root.transform);
  160. tilemapGO.transform.position = Vector3.zero;
  161. var grid = root.GetComponent<Grid>();
  162. // Case 1071703: Do not reset cell size if adding a new Tilemap to an existing Grid of the same layout
  163. if (isometricLayout != grid.cellLayout)
  164. {
  165. Undo.RecordObject(grid, undoMessage);
  166. grid.cellLayout = isometricLayout;
  167. grid.cellSize = new Vector3(1.0f, 0.5f, 1.0f);
  168. }
  169. var tilemapRenderer = tilemapGO.GetComponent<TilemapRenderer>();
  170. tilemapRenderer.sortOrder = TilemapRenderer.SortOrder.TopRight;
  171. GridPaintingState.FlushCache();
  172. Selection.activeObject = tilemapGO;
  173. Undo.RegisterCreatedObjectUndo(tilemapGO, undoMessage);
  174. return root;
  175. }
  176. private static GameObject CreateHexagonalTilemapInternal(GridLayout.CellSwizzle swizzle, string undoMessage, Vector3 cellSize)
  177. {
  178. var valid = FindOrCreateRootGridAndValidate(Grid.CellLayout.Hexagon, true, swizzle, true, cellSize, out var root);
  179. if (!valid)
  180. return null;
  181. var uniqueName = GameObjectUtility.GetUniqueNameForSibling(root.transform, "Tilemap");
  182. var tilemapGO = ObjectFactory.CreateGameObject(uniqueName, typeof(Tilemap), typeof(TilemapRenderer));
  183. tilemapGO.transform.SetParent(root.transform);
  184. tilemapGO.transform.position = Vector3.zero;
  185. var grid = root.GetComponent<Grid>();
  186. Undo.RecordObject(grid, undoMessage);
  187. grid.cellLayout = Grid.CellLayout.Hexagon;
  188. grid.cellSwizzle = swizzle;
  189. grid.cellSize = cellSize;
  190. var tilemap = tilemapGO.GetComponent<Tilemap>();
  191. tilemap.tileAnchor = Vector3.zero;
  192. GridPaintingState.FlushCache();
  193. Selection.activeObject = tilemapGO;
  194. Undo.RegisterCreatedObjectUndo(tilemapGO, undoMessage);
  195. return root;
  196. }
  197. private static GameObject CreateRectangularTilemapInternal(string undoMessage)
  198. {
  199. var valid = FindOrCreateRootGridAndValidate(Grid.CellLayout.Rectangle, false, GridLayout.CellSwizzle.XYZ, false, Vector3.one, out var root);
  200. if (!valid)
  201. return null;
  202. var uniqueName = GameObjectUtility.GetUniqueNameForSibling(root.transform, "Tilemap");
  203. var tilemapGO = ObjectFactory.CreateGameObject(uniqueName, typeof(Tilemap), typeof(TilemapRenderer));
  204. Undo.SetTransformParent(tilemapGO.transform, root.transform, "");
  205. tilemapGO.transform.position = Vector3.zero;
  206. var grid = root.GetComponent<Grid>();
  207. if (Grid.CellLayout.Rectangle != grid.cellLayout)
  208. {
  209. Undo.RecordObject(grid, undoMessage);
  210. grid.cellLayout = Grid.CellLayout.Rectangle;
  211. }
  212. GridPaintingState.FlushCache();
  213. Selection.activeObject = tilemapGO;
  214. Undo.SetCurrentGroupName(undoMessage);
  215. return root;
  216. }
  217. private static bool FindOrCreateRootGridAndValidate(GridLayout.CellLayout gridLayout
  218. , bool changeSwizzle
  219. , GridLayout.CellSwizzle swizzle
  220. , bool changeSize
  221. , Vector3 cellSize
  222. , out GameObject gridGO)
  223. {
  224. gridGO = null;
  225. // Check if active object has a Grid and can be a parent for the Tile Map
  226. if (Selection.activeObject is GameObject)
  227. {
  228. var go = (GameObject)Selection.activeObject;
  229. var parentGrid = go.GetComponentInParent<Grid>();
  230. if (parentGrid != null)
  231. {
  232. if (showDialog
  233. && Application.isHumanControllingUs
  234. && !Application.isBatchMode
  235. && (parentGrid.cellLayout != gridLayout
  236. || (changeSwizzle && parentGrid.cellSwizzle != swizzle)
  237. || (changeSize && Vector3.Distance(parentGrid.cellSize,cellSize) > 0.001f)))
  238. {
  239. var option = EditorUtility.DisplayDialog(Styles.modifyExistingGridTitle
  240. , Styles.modifyExistingGridMessage
  241. , Styles.continueText
  242. , Styles.cancelText);
  243. if (!option)
  244. return false;
  245. }
  246. gridGO = parentGrid.gameObject;
  247. }
  248. }
  249. if (gridGO == null)
  250. {
  251. gridGO = ObjectFactory.CreateGameObject("Grid", typeof(Grid));
  252. gridGO.transform.position = Vector3.zero;
  253. var grid = gridGO.GetComponent<Grid>();
  254. grid.cellSize = new Vector3(1.0f, 1.0f, 0.0f);
  255. Undo.SetCurrentGroupName("Create Grid");
  256. }
  257. return true;
  258. }
  259. }
  260. }