Net-Game/Library/PackageCache/com.unity.2d.tilemap@91afae292a4e/Editor/ObjectCreationMenu/GameObjectCreation.cs
2025-03-28 08:33:16 -04:00

299 lines
14 KiB
C#

using UnityEngine;
using UnityEngine.Tilemaps;
namespace UnityEditor.Tilemaps
{
static class GameObjectCreation
{
private static class Styles
{
public static readonly string rectangularCreateUndo = L10n.Tr("Create Tilemap");
public static readonly string pointTopHexagonCreateUndo = L10n.Tr("Hexagonal Point Top Tilemap");
public static readonly string flatTopHexagonCreateUndo = L10n.Tr("Hexagonal Flat Top Tilemap");
public static readonly string isometricCreateUndo = L10n.Tr("Isometric Tilemap");
public static readonly string isometricZAsYCreateUndo = L10n.Tr("Isometric Z As Y Tilemap");
public static readonly string copyFromTilePaletteUndo = L10n.Tr("Tilemap with Tile Palette Settings");
public static readonly string modifyExistingGridTitle = L10n.Tr("Modify existing Grid");
public static readonly string modifyExistingGridMessage = L10n.Tr("Creating the Tilemap will modify the existing selected Grid. Continue?");
public static readonly string continueText = L10n.Tr("Continue");
public static readonly string cancelText = L10n.Tr("Cancel");
}
enum TilemapMenuPriority : int
{
Rectangular = 3,
HexagonalFlatTop,
HexagonalPointTop,
Isometric,
IsometricZasY
}
internal static bool showDialog = true;
internal static string[] CreateTilemapTargetsNames = new[]
{
"From Tile Palette"
, "Rectangular Tilemap"
, "Hexagonal Point Top Tilemap"
, "Hexagonal Flat Top Tilemap"
, "Isometric Tilemap"
, "Isometric Z As Y Tilemap"
};
internal static void CreateTilemapTargets(int index)
{
switch (index)
{
case 1:
CreateRectangularTilemap();
break;
case 2:
CreateHexagonalPointTopTilemap();
break;
case 3:
CreateHexagonalFlatTopTilemap();
break;
case 4:
CreateIsometricTilemap();
break;
case 5:
CreateIsometricZAsYTilemap();
break;
case 0:
{
var palette = GridPaintingState.palette;
if (palette == null)
return;
var grid = palette.GetComponentInChildren<Grid>();
if (grid == null)
return;
var newSize = grid.cellSize;
var paletteAsset = GridPaletteUtility.GetGridPaletteFromPaletteAsset(palette);
if (paletteAsset != null && paletteAsset.cellSizing == GridPalette.CellSizing.Automatic)
{
newSize = GridPaletteUtility.CalculateAutoCellSize(grid, grid.cellSize);
}
GameObject newGameObject = null;
switch (grid.cellLayout)
{
case GridLayout.CellLayout.Rectangle:
newGameObject = CreateRectangularTilemapInternal(Styles.copyFromTilePaletteUndo);
break;
case GridLayout.CellLayout.Hexagon:
newGameObject = CreateHexagonalTilemapInternal(grid.cellSwizzle,
Styles.copyFromTilePaletteUndo, newSize);
break;
case GridLayout.CellLayout.Isometric:
newGameObject = CreateIsometricTilemapInternal(GridLayout.CellLayout.Isometric, Styles.copyFromTilePaletteUndo);
break;
case GridLayout.CellLayout.IsometricZAsY:
newGameObject = CreateIsometricTilemapInternal(GridLayout.CellLayout.IsometricZAsY, Styles.copyFromTilePaletteUndo);
break;
}
if (newGameObject == null)
return;
var newGrid = newGameObject.GetComponentInChildren<Grid>();
if (newGrid == null)
return;
var tilemap = palette.GetComponentInChildren<Tilemap>();
var newTilemaps = newGameObject.GetComponentsInChildren<Tilemap>();
// Get last new Tilemap child if there are multiple Tilemaps
var newTilemap = newTilemaps != null && newTilemaps.Length > 0 ? newTilemaps[^1] : null;
var tilemapRenderer = palette.GetComponentInChildren<TilemapRenderer>();
var newTilemapRenderer = newTilemap != null ? newTilemap.GetComponent<TilemapRenderer>() : null;
Undo.RecordObjects(new Object[] {newGrid, newTilemap, newTilemapRenderer}, Styles.copyFromTilePaletteUndo);
if (tilemap != null && newTilemap != null)
{
newTilemap.animationFrameRate = tilemap.animationFrameRate;
newTilemap.color = tilemap.color;
newTilemap.tileAnchor = tilemap.tileAnchor;
newTilemap.orientation = tilemap.orientation;
newTilemap.orientationMatrix = tilemap.orientationMatrix;
}
if (tilemapRenderer != null && newTilemapRenderer != null)
{
newTilemapRenderer.mode = tilemapRenderer.mode;
newTilemapRenderer.chunkSize = tilemapRenderer.chunkSize;
newTilemapRenderer.chunkCullingBounds = tilemapRenderer.chunkCullingBounds;
newTilemapRenderer.detectChunkCullingBounds = tilemapRenderer.detectChunkCullingBounds;
newTilemapRenderer.sortOrder = tilemapRenderer.sortOrder;
newTilemapRenderer.maskInteraction = tilemapRenderer.maskInteraction;
newTilemapRenderer.sortingOrder = tilemapRenderer.sortingOrder;
newTilemapRenderer.sortingLayerID = tilemapRenderer.sortingLayerID;
}
newGrid.cellSwizzle = grid.cellSwizzle;
if (newGrid.cellLayout != GridLayout.CellLayout.Hexagon)
newGrid.cellGap = grid.cellGap;
newGrid.cellSize = newSize;
}
break;
}
}
[MenuItem("GameObject/2D Object/Tilemap/Rectangular", priority = (int)TilemapMenuPriority.Rectangular)]
internal static void CreateRectangularTilemap()
{
CreateRectangularTilemapInternal(Styles.rectangularCreateUndo);
}
[MenuItem("GameObject/2D Object/Tilemap/Hexagonal Flat Top", priority = (int)TilemapMenuPriority.HexagonalFlatTop)]
internal static void CreateHexagonalFlatTopTilemap()
{
CreateHexagonalTilemapInternal(GridLayout.CellSwizzle.YXZ, Styles.flatTopHexagonCreateUndo, new Vector3(0.8659766f, 1, 1));
}
[MenuItem("GameObject/2D Object/Tilemap/Hexagonal Point Top", priority = (int)TilemapMenuPriority.HexagonalPointTop)]
internal static void CreateHexagonalPointTopTilemap()
{
CreateHexagonalTilemapInternal(GridLayout.CellSwizzle.XYZ, Styles.pointTopHexagonCreateUndo, new Vector3(0.8659766f, 1, 1));
}
[MenuItem("GameObject/2D Object/Tilemap/Isometric", priority = (int)TilemapMenuPriority.Isometric)]
internal static void CreateIsometricTilemap()
{
CreateIsometricTilemapInternal(GridLayout.CellLayout.Isometric, Styles.isometricCreateUndo);
}
[MenuItem("GameObject/2D Object/Tilemap/Isometric Z as Y", priority = (int)TilemapMenuPriority.IsometricZasY)]
internal static void CreateIsometricZAsYTilemap()
{
CreateIsometricTilemapInternal(GridLayout.CellLayout.IsometricZAsY, Styles.isometricZAsYCreateUndo);
}
private static GameObject CreateIsometricTilemapInternal(GridLayout.CellLayout isometricLayout, string undoMessage)
{
var valid = FindOrCreateRootGridAndValidate(isometricLayout, false, GridLayout.CellSwizzle.XYZ, true, new Vector3(1.0f, 0.5f, 1.0f), out var root);
if (!valid)
return null;
var uniqueName = GameObjectUtility.GetUniqueNameForSibling(root.transform, "Tilemap");
var tilemapGO = ObjectFactory.CreateGameObject(uniqueName, typeof(Tilemap), typeof(TilemapRenderer));
tilemapGO.transform.SetParent(root.transform);
tilemapGO.transform.position = Vector3.zero;
var grid = root.GetComponent<Grid>();
// Case 1071703: Do not reset cell size if adding a new Tilemap to an existing Grid of the same layout
if (isometricLayout != grid.cellLayout)
{
Undo.RecordObject(grid, undoMessage);
grid.cellLayout = isometricLayout;
grid.cellSize = new Vector3(1.0f, 0.5f, 1.0f);
}
var tilemapRenderer = tilemapGO.GetComponent<TilemapRenderer>();
tilemapRenderer.sortOrder = TilemapRenderer.SortOrder.TopRight;
GridPaintingState.FlushCache();
Selection.activeObject = tilemapGO;
Undo.RegisterCreatedObjectUndo(tilemapGO, undoMessage);
return root;
}
private static GameObject CreateHexagonalTilemapInternal(GridLayout.CellSwizzle swizzle, string undoMessage, Vector3 cellSize)
{
var valid = FindOrCreateRootGridAndValidate(Grid.CellLayout.Hexagon, true, swizzle, true, cellSize, out var root);
if (!valid)
return null;
var uniqueName = GameObjectUtility.GetUniqueNameForSibling(root.transform, "Tilemap");
var tilemapGO = ObjectFactory.CreateGameObject(uniqueName, typeof(Tilemap), typeof(TilemapRenderer));
tilemapGO.transform.SetParent(root.transform);
tilemapGO.transform.position = Vector3.zero;
var grid = root.GetComponent<Grid>();
Undo.RecordObject(grid, undoMessage);
grid.cellLayout = Grid.CellLayout.Hexagon;
grid.cellSwizzle = swizzle;
grid.cellSize = cellSize;
var tilemap = tilemapGO.GetComponent<Tilemap>();
tilemap.tileAnchor = Vector3.zero;
GridPaintingState.FlushCache();
Selection.activeObject = tilemapGO;
Undo.RegisterCreatedObjectUndo(tilemapGO, undoMessage);
return root;
}
private static GameObject CreateRectangularTilemapInternal(string undoMessage)
{
var valid = FindOrCreateRootGridAndValidate(Grid.CellLayout.Rectangle, false, GridLayout.CellSwizzle.XYZ, false, Vector3.one, out var root);
if (!valid)
return null;
var uniqueName = GameObjectUtility.GetUniqueNameForSibling(root.transform, "Tilemap");
var tilemapGO = ObjectFactory.CreateGameObject(uniqueName, typeof(Tilemap), typeof(TilemapRenderer));
Undo.SetTransformParent(tilemapGO.transform, root.transform, "");
tilemapGO.transform.position = Vector3.zero;
var grid = root.GetComponent<Grid>();
if (Grid.CellLayout.Rectangle != grid.cellLayout)
{
Undo.RecordObject(grid, undoMessage);
grid.cellLayout = Grid.CellLayout.Rectangle;
}
GridPaintingState.FlushCache();
Selection.activeObject = tilemapGO;
Undo.SetCurrentGroupName(undoMessage);
return root;
}
private static bool FindOrCreateRootGridAndValidate(GridLayout.CellLayout gridLayout
, bool changeSwizzle
, GridLayout.CellSwizzle swizzle
, bool changeSize
, Vector3 cellSize
, out GameObject gridGO)
{
gridGO = null;
// Check if active object has a Grid and can be a parent for the Tile Map
if (Selection.activeObject is GameObject)
{
var go = (GameObject)Selection.activeObject;
var parentGrid = go.GetComponentInParent<Grid>();
if (parentGrid != null)
{
if (showDialog
&& Application.isHumanControllingUs
&& !Application.isBatchMode
&& (parentGrid.cellLayout != gridLayout
|| (changeSwizzle && parentGrid.cellSwizzle != swizzle)
|| (changeSize && Vector3.Distance(parentGrid.cellSize,cellSize) > 0.001f)))
{
var option = EditorUtility.DisplayDialog(Styles.modifyExistingGridTitle
, Styles.modifyExistingGridMessage
, Styles.continueText
, Styles.cancelText);
if (!option)
return false;
}
gridGO = parentGrid.gameObject;
}
}
if (gridGO == null)
{
gridGO = ObjectFactory.CreateGameObject("Grid", typeof(Grid));
gridGO.transform.position = Vector3.zero;
var grid = gridGO.GetComponent<Grid>();
grid.cellSize = new Vector3(1.0f, 1.0f, 0.0f);
Undo.SetCurrentGroupName("Create Grid");
}
return true;
}
}
}