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