A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using System.IO;
4using UnityEditor.PackageManager.UI;
5using UnityEngine;
6using UnityEngine.Tilemaps;
7
8namespace UnityEditor.Tilemaps
9{
10 internal static class DefaultAssetCreation
11 {
12 enum TilePaletteAssetMenuPriority : int
13 {
14 Rectangular = 4,
15 HexagonalFlatTop,
16 HexagonalPointTop,
17 Isometric
18 }
19
20 private const int k_TilePaletteWhiteboxAssetMenuPriority = (int)TilePaletteAssetMenuPriority.Rectangular + 100;
21
22 static internal Action<int, ProjectWindowCallback.EndNameEditAction, string, Texture2D, string> StartNewAssetNameEditingDelegate = ProjectWindowUtil.StartNameEditingIfProjectWindowExists;
23
24 [MenuItem("Assets/Create/2D/Tile Palette/Rectangular", priority = (int)TilePaletteAssetMenuPriority.Rectangular)]
25 static void MenuItem_AssetsCreate2DTilePaletteRectangular(MenuCommand menuCommand)
26 {
27 CreateAssetObject("Rectangular Palette", GridLayout.CellLayout.Rectangle, GridLayout.CellSwizzle.XYZ, GridPalette.CellSizing.Automatic, new Vector3(1, 1, 0));
28 }
29
30 [MenuItem("Assets/Create/2D/Tile Palette/Hexagonal Flat Top", priority = (int)TilePaletteAssetMenuPriority.HexagonalFlatTop)]
31 static void MenuItem_AssetsCreate2DTilePaletteHexagonalFlatTop(MenuCommand menuCommand)
32 {
33 CreateAssetObject("Hexagonal Flat Top Palette", GridLayout.CellLayout.Hexagon, GridLayout.CellSwizzle.YXZ, GridPalette.CellSizing.Manual, new Vector3(0.8659766f, 1, 0));
34 }
35
36 [MenuItem("Assets/Create/2D/Tile Palette/Hexagonal Point Top", priority = (int)TilePaletteAssetMenuPriority.HexagonalPointTop)]
37 static void MenuItem_AssetsCreate2DTilePaletteHexagonalPointedTop(MenuCommand menuCommand)
38 {
39 CreateAssetObject("Hexagonal Point Top Palette", GridLayout.CellLayout.Hexagon, GridLayout.CellSwizzle.XYZ, GridPalette.CellSizing.Manual, new Vector3(0.8659766f, 1, 0));
40 }
41
42 [MenuItem("Assets/Create/2D/Tile Palette/Isometric", priority = (int)TilePaletteAssetMenuPriority.Isometric)]
43 static void MenuItem_AssetsCreate2DTilePaletteIsometric(MenuCommand menuCommand)
44 {
45 CreateAssetObject("Isometric Palette", GridLayout.CellLayout.Isometric, GridLayout.CellSwizzle.XYZ, GridPalette.CellSizing.Manual, new Vector3(1, 0.5f, 0));
46 }
47
48 [InitializeOnLoadMethod]
49 internal static void InitializeWhiteboxSampleMenuItems()
50 {
51 // Defer addition of whitebox sample menu items
52 Menu.menuChanged += ValidateWhiteboxSampleMenuItems;
53 }
54
55 private static string GenerateWhiteboxMenuName(Sample sample)
56 {
57 var name = $"Assets/Create/2D/Tile Palette/{sample.displayName}";
58 name = name.Replace(" Tile Palette", String.Empty);
59 return name;
60 }
61
62 private static void ValidateWhiteboxSampleMenuItems()
63 {
64 Menu.menuChanged -= ValidateWhiteboxSampleMenuItems;
65 CreateWhiteboxSampleMenuItems();
66 }
67
68 private static void CreateWhiteboxSampleMenuItems()
69 {
70 var samples = TilePaletteWhiteboxSamplesUtility.whiteboxSamples;
71 foreach (var sample in samples)
72 {
73 var name = GenerateWhiteboxMenuName(sample);
74 if (Menu.MenuItemExists(name))
75 {
76 continue;
77 }
78 Menu.AddMenuItem(name, String.Empty, false, k_TilePaletteWhiteboxAssetMenuPriority,
79 () => { DuplicateWhiteboxSample(sample); }, null);
80 }
81 }
82
83 private static void DuplicateWhiteboxSample(Sample sample)
84 {
85 var assetSelectionPath = AssetDatabase.GetAssetPath(Selection.activeObject);
86 var isFolder = false;
87 if (!string.IsNullOrEmpty(assetSelectionPath))
88 isFolder = File.GetAttributes(assetSelectionPath).HasFlag(FileAttributes.Directory);
89 var path = ProjectWindowUtil.GetActiveFolderPath();
90 if (isFolder)
91 {
92 path = assetSelectionPath;
93 }
94
95 var destName = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(path, sample.displayName));
96 var icon = EditorGUIUtility.IconContent<GameObject>().image as Texture2D;
97
98 DuplicateWhiteboxPaletteEndNameEditAction action = ScriptableObject.CreateInstance<DuplicateWhiteboxPaletteEndNameEditAction>();
99 action.sample = sample;
100 action.path = path;
101 StartNewAssetNameEditingDelegate(0, action, destName, icon, "");
102 }
103
104 static void CreateAssetObject(string defaultAssetName, GridLayout.CellLayout layout, GridLayout.CellSwizzle swizzle, GridPalette.CellSizing cellSizing, Vector3 cellSize)
105 {
106 var assetSelectionPath = AssetDatabase.GetAssetPath(Selection.activeObject);
107 var isFolder = false;
108 if (!string.IsNullOrEmpty(assetSelectionPath))
109 isFolder = File.GetAttributes(assetSelectionPath).HasFlag(FileAttributes.Directory);
110 var path = ProjectWindowUtil.GetActiveFolderPath();
111 if (isFolder)
112 {
113 path = assetSelectionPath;
114 }
115
116 var destName = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(path, defaultAssetName));
117 var icon = EditorGUIUtility.IconContent<GameObject>().image as Texture2D;
118
119 Dictionary<Vector2Int, TileDragAndDropHoverData> hoverData = null;
120 if (Selection.objects != null && Selection.objects.Length > 0)
121 {
122 var sheets = TileDragAndDrop.GetValidSpritesheets(Selection.objects);
123 var sprites = TileDragAndDrop.GetValidSingleSprites(Selection.objects);
124 var tiles = TileDragAndDrop.GetValidTiles(Selection.objects);
125 var gos = TileDragAndDrop.GetValidGameObjects(Selection.objects);
126 hoverData = TileDragAndDrop.CreateHoverData(sheets, sprites, tiles, gos, layout);
127 }
128
129 CreateAssetEndNameEditAction action = ScriptableObject.CreateInstance<CreateAssetEndNameEditAction>();
130 action.swizzle = swizzle;
131 action.layout = layout;
132 action.cellSize = cellSize;
133 action.cellSizing = cellSizing;
134 action.hoverData = hoverData;
135
136 StartNewAssetNameEditingDelegate(0, action, destName, icon, "");
137 }
138
139 internal class DuplicateWhiteboxPaletteEndNameEditAction : ProjectWindowCallback.EndNameEditAction
140 {
141 public string path;
142 public Sample sample;
143
144 public override void Action(int instanceId, string pathName, string resourceFile)
145 {
146 TilePaletteWhiteboxSamplesUtility.DuplicateWhiteboxSample(sample, path, FileUtil.UnityGetFileName(pathName));
147 }
148 }
149
150 internal class CreateAssetEndNameEditAction : ProjectWindowCallback.EndNameEditAction
151 {
152 public GridLayout.CellLayout layout { get; set; }
153 public GridLayout.CellSwizzle swizzle { get; set; }
154 public Vector3 cellSize { get; set; }
155 public GridPalette.CellSizing cellSizing { get; set; }
156
157 public Dictionary<Vector2Int, TileDragAndDropHoverData> hoverData { get; set; }
158
159 public override void Action(int instanceId, string pathName, string resourceFile)
160 {
161 var directoryName = Path.GetDirectoryName(pathName);
162 var go = GridPaletteUtility.CreateNewPalette(directoryName, Path.GetFileName(pathName), layout,
163 cellSizing, cellSize, swizzle);
164
165 if (hoverData == null)
166 return;
167
168 var tilemap = go.GetComponentInChildren<Tilemap>();
169 var tileSheet = TileDragAndDrop.ConvertToTileSheet(hoverData, directoryName);
170 var i = 0;
171 foreach (var item in hoverData)
172 {
173 if (i >= tileSheet.Count)
174 break;
175
176 var offset = Vector3.zero;
177 if (item.Value.hasOffset)
178 {
179 offset = item.Value.positionOffset - tilemap.tileAnchor;
180 offset.x *= item.Value.scaleFactor.x;
181 offset.y *= item.Value.scaleFactor.y;
182 offset.z *= item.Value.scaleFactor.z;
183 }
184 tilemap.SetTile(new Vector3Int(item.Key.x, item.Key.y), tileSheet[i++]);
185 }
186 EditorUtility.SetDirty(go);
187 AssetDatabase.SaveAssetIfDirty(go);
188
189 Selection.activeObject = go;
190 }
191 }
192 }
193}