Sin descripción
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.

GridPaintPaletteWindow.cs 61KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor.EditorTools;
  5. using UnityEditor.ShortcutManagement;
  6. using UnityEngine;
  7. using UnityEngine.Tilemaps;
  8. using Event = UnityEngine.Event;
  9. using Object = UnityEngine.Object;
  10. using UnityEditor.SceneManagement;
  11. namespace UnityEditor.Tilemaps
  12. {
  13. internal class GridPaintPaletteWindow : EditorWindow
  14. {
  15. internal enum TilemapFocusMode
  16. {
  17. None = 0,
  18. Tilemap = 1,
  19. Grid = 2
  20. }
  21. private static readonly string k_TilemapFocusModeEditorPref = "TilemapFocusMode";
  22. internal static TilemapFocusMode focusMode
  23. {
  24. get
  25. {
  26. return (TilemapFocusMode)EditorPrefs.GetInt(k_TilemapFocusModeEditorPref, (int)TilemapFocusMode.None);
  27. }
  28. set
  29. {
  30. EditorPrefs.SetInt(k_TilemapFocusModeEditorPref, (int)value);
  31. }
  32. }
  33. private static readonly string k_TilemapLastPaletteEditorPref = "TilemapLastPalette";
  34. private string lastTilemapPalette
  35. {
  36. get
  37. {
  38. return EditorPrefs.GetString(k_TilemapLastPaletteEditorPref, "");
  39. }
  40. set
  41. {
  42. EditorPrefs.SetString(k_TilemapLastPaletteEditorPref, value);
  43. }
  44. }
  45. private static class MouseStyles
  46. {
  47. // The following paths match the enums in OperatingSystemFamily
  48. public static readonly string[] mouseCursorOSPath =
  49. {
  50. "", // Other OS
  51. "Cursors/macOS",
  52. "Cursors/Windows",
  53. "Cursors/Linux",
  54. };
  55. // The following paths match the enums in OperatingSystemFamily
  56. public static readonly Vector2[] mouseCursorOSHotspot =
  57. {
  58. Vector2.zero, // Other OS
  59. new Vector2(6f, 4f),
  60. new Vector2(6f, 4f),
  61. new Vector2(6f, 4f),
  62. };
  63. // The following paths match the enums in sceneViewEditModes above
  64. public static readonly string[] mouseCursorTexturePaths =
  65. {
  66. "",
  67. "Grid.MoveTool.png",
  68. "Grid.PaintTool.png",
  69. "Grid.BoxTool.png",
  70. "Grid.PickingTool.png",
  71. "Grid.EraserTool.png",
  72. "Grid.FillTool.png",
  73. };
  74. public static readonly Texture2D[] mouseCursorTextures;
  75. static MouseStyles()
  76. {
  77. mouseCursorTextures = new Texture2D[mouseCursorTexturePaths.Length];
  78. int osIndex = (int)SystemInfo.operatingSystemFamily;
  79. for (int i = 0; i < mouseCursorTexturePaths.Length; ++i)
  80. {
  81. if ((mouseCursorOSPath[osIndex] != null && mouseCursorOSPath[osIndex].Length > 0)
  82. && (mouseCursorTexturePaths[i] != null && mouseCursorTexturePaths[i].Length > 0))
  83. {
  84. string cursorPath = Utils.Paths.Combine(mouseCursorOSPath[osIndex], mouseCursorTexturePaths[i]);
  85. mouseCursorTextures[i] = EditorGUIUtility.LoadRequired(cursorPath) as Texture2D;
  86. }
  87. else
  88. mouseCursorTextures[i] = null;
  89. }
  90. }
  91. }
  92. private static class Styles
  93. {
  94. public static readonly GUIContent emptyProjectInfo = EditorGUIUtility.TrTextContent("Create a new palette in the dropdown above.");
  95. public static readonly GUIContent emptyPaletteInfo = EditorGUIUtility.TrTextContent("Drag Tile, Sprite or Sprite Texture assets here.");
  96. public static readonly GUIContent invalidPaletteInfo = EditorGUIUtility.TrTextContent("This is an invalid palette. Did you delete the palette asset?");
  97. public static readonly GUIContent invalidGridInfo = EditorGUIUtility.TrTextContent("The palette has an invalid Grid. Did you add a Grid to the palette asset?");
  98. public static readonly GUIContent selectPaintTarget = EditorGUIUtility.TrTextContent("Select Paint Target");
  99. public static readonly GUIContent selectPalettePrefab = EditorGUIUtility.TrTextContent("Select Palette Prefab");
  100. public static readonly GUIContent selectTileAsset = EditorGUIUtility.TrTextContent("Select Tile Asset");
  101. public static readonly GUIContent unlockPaletteEditing = EditorGUIUtility.TrTextContent("Unlock Palette Editing");
  102. public static readonly GUIContent lockPaletteEditing = EditorGUIUtility.TrTextContent("Lock Palette Editing");
  103. public static readonly GUIContent openTilePalettePreferences = EditorGUIUtility.TrTextContent("Open Tile Palette Preferences");
  104. public static readonly GUIContent createNewPalette = EditorGUIUtility.TrTextContent("Create New Palette");
  105. public static readonly GUIContent activeTargetLabel = EditorGUIUtility.TrTextContent("Active Tilemap", "Specifies the currently active Tilemap used for painting in the Scene View.");
  106. public static readonly GUIContent prefabWarningIcon = EditorGUIUtility.TrIconContent("console.warnicon.sml", "Editing Tilemaps in Prefabs will have better performance if edited in Prefab Mode.");
  107. public static readonly GUIContent tilePalette = EditorGUIUtility.TrTextContent("Tile Palette");
  108. public static readonly GUIContent edit = EditorGUIUtility.TrTextContent("Edit", "Toggle to edit current Tile Palette");
  109. public static readonly GUIContent editModified = EditorGUIUtility.TrTextContent("Edit*", "Toggle to save edits for current Tile Palette");
  110. public static readonly GUIContent gridGizmo = EditorGUIUtility.TrTextContent("Grid", "Toggle visibility of the Grid in the Tile Palette");
  111. public static readonly GUIContent gizmos = EditorGUIUtility.TrTextContent("Gizmos", "Toggle visibility of Gizmos in the Tile Palette");
  112. public static readonly GUIContent lockZPosition = EditorGUIUtility.TrTextContent("Lock Z Position", "Toggle editing of Z position");
  113. public static readonly GUIContent zPosition = EditorGUIUtility.TrTextContent("Z Position", "Set a Z position for the active Brush for painting");
  114. public static readonly GUIContent resetZPosition = EditorGUIUtility.TrTextContent("Reset", "Reset Z position for the active Brush");
  115. public static readonly GUIStyle ToolbarTitleStyle = "Toolbar";
  116. public static readonly GUIStyle dragHandle = "RL DragHandle";
  117. public static readonly float dragPadding = 3f;
  118. public static readonly GUILayoutOption[] dropdownOptions = { GUILayout.Width(k_DropdownWidth) };
  119. }
  120. private class TilePaletteSaveScope : IDisposable
  121. {
  122. private GameObject m_GameObject;
  123. public TilePaletteSaveScope(GameObject paletteInstance)
  124. {
  125. m_GameObject = paletteInstance;
  126. if (m_GameObject != null)
  127. {
  128. GridPaintingState.savingPalette = true;
  129. SetHideFlagsRecursively(paletteInstance, HideFlags.HideInHierarchy);
  130. foreach (var renderer in paletteInstance.GetComponentsInChildren<Renderer>())
  131. renderer.gameObject.layer = 0;
  132. }
  133. }
  134. public void Dispose()
  135. {
  136. if (m_GameObject != null)
  137. {
  138. SetHideFlagsRecursively(m_GameObject, HideFlags.HideAndDontSave);
  139. GridPaintingState.savingPalette = false;
  140. }
  141. }
  142. private void SetHideFlagsRecursively(GameObject root, HideFlags flags)
  143. {
  144. root.hideFlags = flags;
  145. for (int i = 0; i < root.transform.childCount; i++)
  146. SetHideFlagsRecursively(root.transform.GetChild(i).gameObject, flags);
  147. }
  148. }
  149. internal class TilePaletteProperties
  150. {
  151. public enum PrefabEditModeSettings
  152. {
  153. EnableDialog = 0,
  154. EditInPrefabMode = 1,
  155. EditInScene = 2
  156. }
  157. public static readonly string targetEditModeDialogTitle = L10n.Tr("Open in Prefab Mode");
  158. public static readonly string targetEditModeDialogMessage = L10n.Tr("Editing Tilemaps in Prefabs will have better performance if edited in Prefab Mode. Do you want to open it in Prefab Mode or edit it in the Scene?");
  159. public static readonly string targetEditModeDialogYes = L10n.Tr("Prefab Mode");
  160. public static readonly string targetEditModeDialogChange = L10n.Tr("Preferences");
  161. public static readonly string targetEditModeDialogNo = L10n.Tr("Scene");
  162. public static readonly string targetEditModeEditorPref = "TilePalette.TargetEditMode";
  163. public static readonly string targetEditModeLookup = "Target Edit Mode";
  164. public static readonly string tilePalettePreferencesLookup = "Tile Palette";
  165. public static readonly GUIContent targetEditModeDialogLabel = EditorGUIUtility.TrTextContent(targetEditModeLookup, "Controls the behaviour of editing a Prefab Instance when one is selected as the Active Target in the Tile Palette");
  166. }
  167. private static readonly GridBrushBase.Tool[] k_SceneViewEditModes =
  168. {
  169. GridBrushBase.Tool.Select,
  170. GridBrushBase.Tool.Move,
  171. GridBrushBase.Tool.Paint,
  172. GridBrushBase.Tool.Box,
  173. GridBrushBase.Tool.Pick,
  174. GridBrushBase.Tool.Erase,
  175. GridBrushBase.Tool.FloodFill
  176. };
  177. private const float k_DropdownWidth = 200f;
  178. private const float k_ActiveTargetLabelWidth = 90f;
  179. private const float k_ActiveTargetDropdownWidth = 130f;
  180. private const float k_ActiveTargetWarningSize = 20f;
  181. private const float k_TopAreaHeight = 104f;
  182. private const float k_MinBrushInspectorHeight = 50f;
  183. private const float k_MinClipboardHeight = 200f;
  184. private const float k_ToolbarHeight = 17f;
  185. private const float k_ResizerDragRectPadding = 10f;
  186. private static readonly Vector2 k_MinWindowSize = new Vector2(k_ActiveTargetLabelWidth + k_ActiveTargetDropdownWidth + k_ActiveTargetWarningSize, 200f);
  187. private PaintableSceneViewGrid m_PaintableSceneViewGrid;
  188. readonly TilemapEditorTool.ShortcutContext m_ShortcutContext = new TilemapEditorTool.ShortcutContext { active = true };
  189. [FormerlyPrefKeyAs("Grid Painting/Select", "s")]
  190. [Shortcut("Grid Painting/Select", typeof(TilemapEditorTool.ShortcutContext), KeyCode.S)]
  191. static void GridSelectKey()
  192. {
  193. TilemapEditorTool.ToggleActiveEditorTool(typeof(SelectTool));
  194. }
  195. [FormerlyPrefKeyAs("Grid Painting/Move", "m")]
  196. [Shortcut("Grid Painting/Move", typeof(TilemapEditorTool.ShortcutContext), KeyCode.M)]
  197. static void GridMoveKey()
  198. {
  199. TilemapEditorTool.ToggleActiveEditorTool(typeof(MoveTool));
  200. }
  201. [FormerlyPrefKeyAs("Grid Painting/Brush", "b")]
  202. [Shortcut("Grid Painting/Brush", typeof(TilemapEditorTool.ShortcutContext), KeyCode.B)]
  203. static void GridBrushKey()
  204. {
  205. TilemapEditorTool.ToggleActiveEditorTool(typeof(PaintTool));
  206. }
  207. [FormerlyPrefKeyAs("Grid Painting/Rectangle", "u")]
  208. [Shortcut("Grid Painting/Rectangle", typeof(TilemapEditorTool.ShortcutContext), KeyCode.U)]
  209. static void GridRectangleKey()
  210. {
  211. TilemapEditorTool.ToggleActiveEditorTool(typeof(BoxTool));
  212. }
  213. [FormerlyPrefKeyAs("Grid Painting/Picker", "i")]
  214. [Shortcut("Grid Painting/Picker", typeof(TilemapEditorTool.ShortcutContext), KeyCode.I)]
  215. static void GridPickerKey()
  216. {
  217. TilemapEditorTool.ToggleActiveEditorTool(typeof(PickingTool));
  218. }
  219. [FormerlyPrefKeyAs("Grid Painting/Erase", "d")]
  220. [Shortcut("Grid Painting/Erase", typeof(TilemapEditorTool.ShortcutContext), KeyCode.D)]
  221. static void GridEraseKey()
  222. {
  223. TilemapEditorTool.ToggleActiveEditorTool(typeof(EraseTool));
  224. }
  225. [FormerlyPrefKeyAs("Grid Painting/Fill", "g")]
  226. [Shortcut("Grid Painting/Fill", typeof(TilemapEditorTool.ShortcutContext), KeyCode.G)]
  227. static void GridFillKey()
  228. {
  229. TilemapEditorTool.ToggleActiveEditorTool(typeof(FillTool));
  230. }
  231. static void RotateBrush(GridBrushBase.RotationDirection direction)
  232. {
  233. GridPaintingState.gridBrush.Rotate(direction, GridPaintingState.activeGrid.cellLayout);
  234. GridPaintingState.activeGrid.Repaint();
  235. }
  236. [FormerlyPrefKeyAs("Grid Painting/Rotate Clockwise", "]")]
  237. [Shortcut("Grid Painting/Rotate Clockwise", typeof(TilemapEditorTool.ShortcutContext), KeyCode.RightBracket)]
  238. static void RotateBrushClockwise()
  239. {
  240. if (GridPaintingState.gridBrush != null && GridPaintingState.activeGrid != null)
  241. RotateBrush(GridBrushBase.RotationDirection.Clockwise);
  242. }
  243. [FormerlyPrefKeyAs("Grid Painting/Rotate Anti-Clockwise", "[")]
  244. [Shortcut("Grid Painting/Rotate Anti-Clockwise", typeof(TilemapEditorTool.ShortcutContext), KeyCode.LeftBracket)]
  245. static void RotateBrushAntiClockwise()
  246. {
  247. if (GridPaintingState.gridBrush != null && GridPaintingState.activeGrid != null)
  248. RotateBrush(GridBrushBase.RotationDirection.CounterClockwise);
  249. }
  250. static void FlipBrush(GridBrushBase.FlipAxis axis)
  251. {
  252. GridPaintingState.gridBrush.Flip(axis, GridPaintingState.activeGrid.cellLayout);
  253. GridPaintingState.activeGrid.Repaint();
  254. }
  255. [FormerlyPrefKeyAs("Grid Painting/Flip X", "#[")]
  256. [Shortcut("Grid Painting/Flip X", typeof(TilemapEditorTool.ShortcutContext), KeyCode.LeftBracket, ShortcutModifiers.Shift)]
  257. static void FlipBrushX()
  258. {
  259. if (GridPaintingState.gridBrush != null && GridPaintingState.activeGrid != null)
  260. FlipBrush(GridBrushBase.FlipAxis.X);
  261. }
  262. [FormerlyPrefKeyAs("Grid Painting/Flip Y", "#]")]
  263. [Shortcut("Grid Painting/Flip Y", typeof(TilemapEditorTool.ShortcutContext), KeyCode.RightBracket, ShortcutModifiers.Shift)]
  264. static void FlipBrushY()
  265. {
  266. if (GridPaintingState.gridBrush != null && GridPaintingState.activeGrid != null)
  267. FlipBrush(GridBrushBase.FlipAxis.Y);
  268. }
  269. static void ChangeBrushZ(int change)
  270. {
  271. GridPaintingState.gridBrush.ChangeZPosition(change);
  272. GridPaintingState.activeGrid.ChangeZPosition(change);
  273. GridPaintingState.activeGrid.Repaint();
  274. foreach (var window in GridPaintPaletteWindow.instances)
  275. {
  276. window.Repaint();
  277. }
  278. }
  279. [Shortcut("Grid Painting/Increase Z", typeof(TilemapEditorTool.ShortcutContext), KeyCode.Minus)]
  280. static void IncreaseBrushZ()
  281. {
  282. if (GridPaintingState.gridBrush != null
  283. && GridPaintingState.activeGrid != null
  284. && GridPaintingState.activeBrushEditor != null
  285. && GridPaintingState.activeBrushEditor.canChangeZPosition)
  286. ChangeBrushZ(1);
  287. }
  288. [Shortcut("Grid Painting/Decrease Z", typeof(TilemapEditorTool.ShortcutContext), KeyCode.Equals)]
  289. static void DecreaseBrushZ()
  290. {
  291. if (GridPaintingState.gridBrush != null
  292. && GridPaintingState.activeGrid != null
  293. && GridPaintingState.activeBrushEditor != null
  294. && GridPaintingState.activeBrushEditor.canChangeZPosition)
  295. ChangeBrushZ(-1);
  296. }
  297. internal static void PreferencesGUI()
  298. {
  299. using (new SettingsWindow.GUIScope())
  300. {
  301. EditorGUI.BeginChangeCheck();
  302. var val = (TilePaletteProperties.PrefabEditModeSettings)EditorGUILayout.EnumPopup(TilePaletteProperties.targetEditModeDialogLabel, (TilePaletteProperties.PrefabEditModeSettings)EditorPrefs.GetInt(TilePaletteProperties.targetEditModeEditorPref, 0));
  303. if (EditorGUI.EndChangeCheck())
  304. {
  305. EditorPrefs.SetInt(TilePaletteProperties.targetEditModeEditorPref, (int)val);
  306. }
  307. }
  308. }
  309. private static List<GridPaintPaletteWindow> s_Instances;
  310. public static List<GridPaintPaletteWindow> instances
  311. {
  312. get
  313. {
  314. if (s_Instances == null)
  315. s_Instances = new List<GridPaintPaletteWindow>();
  316. return s_Instances;
  317. }
  318. }
  319. public static bool isActive
  320. {
  321. get
  322. {
  323. return s_Instances != null && s_Instances.Count > 0;
  324. }
  325. }
  326. [SerializeField]
  327. private PreviewResizer m_PreviewResizer;
  328. private GridPalettesDropdown m_PaletteDropdown;
  329. [SerializeField]
  330. private GameObject m_Palette;
  331. [SerializeField]
  332. private bool m_DrawGridGizmo = true;
  333. internal bool drawGridGizmo
  334. {
  335. get { return m_DrawGridGizmo; }
  336. }
  337. [SerializeField]
  338. private bool m_DrawGizmos;
  339. internal bool drawGizmos
  340. {
  341. get { return m_DrawGizmos; }
  342. }
  343. public GameObject palette
  344. {
  345. get
  346. {
  347. return m_Palette;
  348. }
  349. set
  350. {
  351. if (m_Palette != value)
  352. {
  353. clipboardView.OnBeforePaletteSelectionChanged();
  354. m_Palette = value;
  355. clipboardView.OnAfterPaletteSelectionChanged();
  356. lastTilemapPalette = AssetDatabase.GetAssetPath(m_Palette);
  357. GridPaintingState.OnPaletteChanged(m_Palette);
  358. Repaint();
  359. }
  360. }
  361. }
  362. private GameObject m_PaletteInstance;
  363. public GameObject paletteInstance
  364. {
  365. get
  366. {
  367. return m_PaletteInstance;
  368. }
  369. }
  370. private bool m_DelayedResetPaletteInstance;
  371. private bool m_Enabled;
  372. public GridPaintPaletteClipboard clipboardView { get; private set; }
  373. private Vector2 m_BrushScroll;
  374. private GridBrushEditorBase m_PreviousToolActivatedEditor;
  375. private GridBrushBase.Tool m_PreviousToolActivated;
  376. private PreviewRenderUtility m_PreviewUtility;
  377. public PreviewRenderUtility previewUtility
  378. {
  379. get
  380. {
  381. if (m_Enabled && m_PreviewUtility == null)
  382. InitPreviewUtility();
  383. return m_PreviewUtility;
  384. }
  385. }
  386. private void OnSelectionChange()
  387. {
  388. // Update active palette if user has selected a palette prefab
  389. var selectedObject = Selection.activeGameObject;
  390. if (selectedObject != null)
  391. {
  392. bool isPrefab = EditorUtility.IsPersistent(selectedObject) || (selectedObject.hideFlags & HideFlags.NotEditable) != 0;
  393. if (isPrefab)
  394. {
  395. var assetPath = AssetDatabase.GetAssetPath(selectedObject);
  396. var allAssets = AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath);
  397. foreach (var asset in allAssets)
  398. {
  399. if (asset != null && asset.GetType() == typeof(GridPalette))
  400. {
  401. var targetPalette = (GameObject)AssetDatabase.LoadMainAssetAtPath(assetPath);
  402. if (targetPalette != palette)
  403. {
  404. palette = targetPalette;
  405. Repaint();
  406. }
  407. break;
  408. }
  409. }
  410. }
  411. }
  412. }
  413. private void OnGUI()
  414. {
  415. HandleContextMenu();
  416. EditorGUILayout.BeginVertical();
  417. GUILayout.Space(10f);
  418. EditorGUILayout.BeginHorizontal();
  419. float leftMargin = (Screen.width / EditorGUIUtility.pixelsPerPoint - TilemapEditorTool.tilemapEditorToolsToolbarSize) * 0.5f;
  420. GUILayout.Space(leftMargin);
  421. DoTilemapToolbar();
  422. GUILayout.Space(leftMargin);
  423. EditorGUILayout.EndHorizontal();
  424. EditorGUILayout.BeginHorizontal();
  425. leftMargin = (Screen.width / EditorGUIUtility.pixelsPerPoint - (k_ActiveTargetLabelWidth + k_ActiveTargetDropdownWidth)) * 0.5f;
  426. GUILayout.Space(leftMargin);
  427. DoActiveTargetsGUI();
  428. GUILayout.Space(leftMargin);
  429. EditorGUILayout.EndHorizontal();
  430. GUILayout.Space(6f);
  431. EditorGUILayout.EndVertical();
  432. EditorGUILayout.BeginVertical();
  433. Rect clipboardToolbarRect = EditorGUILayout.BeginHorizontal(GUIContent.none, Styles.ToolbarTitleStyle);
  434. DoClipboardHeader();
  435. EditorGUILayout.EndHorizontal();
  436. ConvertGridPrefabToPalette(clipboardToolbarRect);
  437. Rect dragRect = new Rect(k_DropdownWidth + k_ResizerDragRectPadding, 0, position.width - k_DropdownWidth - k_ResizerDragRectPadding, k_ToolbarHeight);
  438. float brushInspectorSize = m_PreviewResizer.ResizeHandle(position, k_MinBrushInspectorHeight, k_MinClipboardHeight, k_ToolbarHeight, dragRect);
  439. float clipboardHeight = position.height - brushInspectorSize - k_TopAreaHeight;
  440. Rect clipboardRect = new Rect(0f, clipboardToolbarRect.yMax, position.width, clipboardHeight);
  441. OnClipboardGUI(clipboardRect);
  442. EditorGUILayout.EndVertical();
  443. GUILayout.Space(clipboardRect.height);
  444. EditorGUILayout.BeginVertical();
  445. EditorGUILayout.BeginHorizontal(GUIContent.none, Styles.ToolbarTitleStyle);
  446. DoBrushesDropdownToolbar();
  447. EditorGUILayout.EndHorizontal();
  448. m_BrushScroll = GUILayout.BeginScrollView(m_BrushScroll, false, false);
  449. GUILayout.Space(4f);
  450. OnBrushInspectorGUI();
  451. GUILayout.EndScrollView();
  452. EditorGUILayout.EndVertical();
  453. Color oldColor = Handles.color;
  454. Handles.color = Color.black;
  455. Handles.DrawLine(new Vector3(0, clipboardRect.yMax + 0.5f, 0), new Vector3(Screen.width, clipboardRect.yMax + 0.5f, 0));
  456. Handles.color = Color.black.AlphaMultiplied(0.33f);
  457. Handles.DrawLine(new Vector3(0, GUILayoutUtility.GetLastRect().yMax + 0.5f, 0), new Vector3(Screen.width, GUILayoutUtility.GetLastRect().yMax + 0.5f, 0));
  458. Handles.color = oldColor;
  459. EditorGUILayout.BeginVertical();
  460. GUILayout.Space(2f);
  461. EditorGUILayout.EndVertical();
  462. // Keep repainting until all previews are loaded
  463. if (AssetPreview.IsLoadingAssetPreviews(GetInstanceID()))
  464. Repaint();
  465. // Release keyboard focus on click to empty space
  466. if (Event.current.type == EventType.MouseDown)
  467. GUIUtility.keyboardControl = 0;
  468. }
  469. static void DoTilemapToolbar()
  470. {
  471. EditorTool active = EditorToolManager.activeTool;
  472. EditorTool selected;
  473. if (EditorGUILayout.EditorToolbar(GUIContent.none, active, TilemapEditorTool.tilemapEditorTools, out selected))
  474. {
  475. if (active == selected)
  476. ToolManager.RestorePreviousPersistentTool();
  477. else
  478. ToolManager.SetActiveTool(selected);
  479. }
  480. }
  481. public void DelayedResetPreviewInstance()
  482. {
  483. m_DelayedResetPaletteInstance = true;
  484. }
  485. public void ResetPreviewInstance()
  486. {
  487. if (m_PreviewUtility == null)
  488. InitPreviewUtility();
  489. Stack<int> childPositions = null;
  490. if (paletteInstance != null && GridSelection.active && GridSelection.target.transform.IsChildOf(paletteInstance.transform))
  491. {
  492. childPositions = new Stack<int>();
  493. var transform = GridSelection.target.transform;
  494. while (transform != null && transform != paletteInstance.transform)
  495. {
  496. childPositions.Push(transform.GetSiblingIndex());
  497. transform = transform.parent;
  498. }
  499. }
  500. m_DelayedResetPaletteInstance = false;
  501. DestroyPreviewInstance();
  502. if (palette != null)
  503. {
  504. m_PaletteInstance = previewUtility.InstantiatePrefabInScene(palette);
  505. // Disconnecting prefabs is no longer possible.
  506. // If performance of overrides on palette palette instance turns out to be a problem.
  507. // unpack the prefab instance here, and overwrite the prefab later instead of reconnecting.
  508. PrefabUtility.UnpackPrefabInstance(m_PaletteInstance, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction);
  509. EditorUtility.InitInstantiatedPreviewRecursive(m_PaletteInstance);
  510. m_PaletteInstance.transform.position = new Vector3(0, 0, 0);
  511. m_PaletteInstance.transform.rotation = Quaternion.identity;
  512. m_PaletteInstance.transform.localScale = Vector3.one;
  513. GridPalette paletteAsset = GridPaletteUtility.GetGridPaletteFromPaletteAsset(palette);
  514. if (paletteAsset != null)
  515. {
  516. if (paletteAsset.cellSizing == GridPalette.CellSizing.Automatic)
  517. {
  518. Grid grid = m_PaletteInstance.GetComponent<Grid>();
  519. if (grid != null)
  520. {
  521. grid.cellSize = GridPaletteUtility.CalculateAutoCellSize(grid, grid.cellSize);
  522. }
  523. else
  524. {
  525. Debug.LogWarning("Grid component not found from: " + palette.name);
  526. }
  527. }
  528. previewUtility.camera.transparencySortMode = paletteAsset.transparencySortMode;
  529. previewUtility.camera.transparencySortAxis = paletteAsset.transparencySortAxis;
  530. }
  531. else
  532. {
  533. Debug.LogWarning("GridPalette subasset not found from: " + palette.name);
  534. previewUtility.camera.transparencySortMode = TransparencySortMode.Default;
  535. previewUtility.camera.transparencySortAxis = new Vector3(0f, 0f, 1f);
  536. }
  537. foreach (var transform in m_PaletteInstance.GetComponentsInChildren<Transform>())
  538. transform.gameObject.hideFlags = HideFlags.HideAndDontSave;
  539. // Show all renderers from Palettes from previous versions
  540. PreviewRenderUtility.SetEnabledRecursive(m_PaletteInstance, true);
  541. clipboardView.ResetPreviewMesh();
  542. if (childPositions != null)
  543. {
  544. var transform = paletteInstance.transform;
  545. while (childPositions.Count > 0)
  546. {
  547. var siblingIndex = childPositions.Pop();
  548. if (siblingIndex < transform.childCount)
  549. transform = transform.GetChild(siblingIndex);
  550. }
  551. GridSelection.Select(transform.gameObject, GridSelection.position);
  552. }
  553. }
  554. }
  555. public void DestroyPreviewInstance()
  556. {
  557. if (m_PaletteInstance != null)
  558. {
  559. Undo.ClearUndo(m_PaletteInstance);
  560. DestroyImmediate(m_PaletteInstance);
  561. }
  562. }
  563. public void InitPreviewUtility()
  564. {
  565. m_PreviewUtility = new PreviewRenderUtility(true, true);
  566. m_PreviewUtility.camera.orthographic = true;
  567. m_PreviewUtility.camera.orthographicSize = 5f;
  568. m_PreviewUtility.camera.transform.position = new Vector3(0f, 0f, -10f);
  569. m_PreviewUtility.ambientColor = new Color(1f, 1f, 1f, 0);
  570. ResetPreviewInstance();
  571. clipboardView.SetupPreviewCameraOnInit();
  572. }
  573. private void HandleContextMenu()
  574. {
  575. if (Event.current.type == EventType.ContextClick)
  576. {
  577. DoContextMenu();
  578. Event.current.Use();
  579. }
  580. }
  581. public void SavePalette()
  582. {
  583. if (paletteInstance != null && palette != null)
  584. {
  585. using (new TilePaletteSaveScope(paletteInstance))
  586. {
  587. string path = AssetDatabase.GetAssetPath(palette);
  588. PrefabUtility.SaveAsPrefabAssetAndConnect(paletteInstance, path, InteractionMode.AutomatedAction);
  589. }
  590. ResetPreviewInstance();
  591. Repaint();
  592. }
  593. }
  594. private void DoContextMenu()
  595. {
  596. GenericMenu pm = new GenericMenu();
  597. if (GridPaintingState.scenePaintTarget != null)
  598. pm.AddItem(Styles.selectPaintTarget, false, SelectPaintTarget);
  599. else
  600. pm.AddDisabledItem(Styles.selectPaintTarget);
  601. if (palette != null)
  602. pm.AddItem(Styles.selectPalettePrefab, false, SelectPaletteAsset);
  603. else
  604. pm.AddDisabledItem(Styles.selectPalettePrefab);
  605. if (clipboardView.activeTile != null)
  606. pm.AddItem(Styles.selectTileAsset, false, SelectTileAsset);
  607. else
  608. pm.AddDisabledItem(Styles.selectTileAsset);
  609. pm.AddSeparator("");
  610. if (clipboardView.unlocked)
  611. pm.AddItem(Styles.lockPaletteEditing, false, FlipLocked);
  612. else
  613. pm.AddItem(Styles.unlockPaletteEditing, false, FlipLocked);
  614. pm.AddItem(Styles.openTilePalettePreferences, false, OpenTilePalettePreferences);
  615. pm.ShowAsContext();
  616. }
  617. private void OpenTilePalettePreferences()
  618. {
  619. var settingsWindow = SettingsWindow.Show(SettingsScope.User);
  620. settingsWindow.FilterProviders(TilePaletteProperties.tilePalettePreferencesLookup);
  621. }
  622. private void FlipLocked()
  623. {
  624. clipboardView.unlocked = !clipboardView.unlocked;
  625. }
  626. private void SelectPaintTarget()
  627. {
  628. Selection.activeObject = GridPaintingState.scenePaintTarget;
  629. }
  630. private void SelectPaletteAsset()
  631. {
  632. Selection.activeObject = palette;
  633. }
  634. private void SelectTileAsset()
  635. {
  636. Selection.activeObject = clipboardView.activeTile;
  637. }
  638. private bool NotOverridingColor(GridBrush defaultGridBrush)
  639. {
  640. foreach (var cell in defaultGridBrush.cells)
  641. {
  642. TileBase tile = cell.tile;
  643. if (tile is Tile && ((tile as Tile).flags & TileFlags.LockColor) == 0)
  644. {
  645. return true;
  646. }
  647. }
  648. return false;
  649. }
  650. private void DoBrushesDropdownToolbar()
  651. {
  652. GUIContent content = GUIContent.Temp(GridPaintingState.gridBrush.name);
  653. if (EditorGUILayout.DropdownButton(content, FocusType.Passive, EditorStyles.toolbarPopup, Styles.dropdownOptions))
  654. {
  655. var menuData = new GridBrushesDropdown.MenuItemProvider();
  656. var flexibleMenu = new GridBrushesDropdown(menuData, GridPaletteBrushes.brushes.IndexOf(GridPaintingState.gridBrush), null, SelectBrush, k_DropdownWidth);
  657. PopupWindow.Show(GUILayoutUtility.topLevel.GetLast(), flexibleMenu);
  658. }
  659. if (Event.current.type == EventType.Repaint)
  660. {
  661. var dragRect = GUILayoutUtility.GetLastRect();
  662. var dragIconRect = new Rect();
  663. dragIconRect.x = dragRect.x + dragRect.width + Styles.dragPadding;
  664. dragIconRect.y = dragRect.y + (dragRect.height - Styles.dragHandle.fixedHeight) / 2 + 1;
  665. dragIconRect.width = position.width - (dragIconRect.x) - Styles.dragPadding;
  666. dragIconRect.height = Styles.dragHandle.fixedHeight;
  667. Styles.dragHandle.Draw(dragIconRect, GUIContent.none, false, false, false, false);
  668. }
  669. GUILayout.FlexibleSpace();
  670. }
  671. private void SelectBrush(int i, object o)
  672. {
  673. GridPaintingState.gridBrush = GridPaletteBrushes.brushes[i];
  674. }
  675. public void OnEnable()
  676. {
  677. m_Enabled = true;
  678. instances.Add(this);
  679. if (clipboardView == null)
  680. {
  681. clipboardView = CreateInstance<GridPaintPaletteClipboard>();
  682. clipboardView.owner = this;
  683. clipboardView.hideFlags = HideFlags.HideAndDontSave;
  684. clipboardView.unlocked = false;
  685. }
  686. if (m_PaintableSceneViewGrid == null)
  687. {
  688. m_PaintableSceneViewGrid = CreateInstance<PaintableSceneViewGrid>();
  689. m_PaintableSceneViewGrid.hideFlags = HideFlags.HideAndDontSave;
  690. }
  691. GridPaletteBrushes.FlushCache();
  692. ShortcutIntegration.instance.profileManager.shortcutBindingChanged += UpdateTooltips;
  693. GridSelection.gridSelectionChanged += OnGridSelectionChanged;
  694. GridPaintingState.RegisterPainterInterest(this);
  695. GridPaintingState.scenePaintTargetChanged += OnScenePaintTargetChanged;
  696. GridPaintingState.brushChanged += OnBrushChanged;
  697. SceneView.duringSceneGui += OnSceneViewGUI;
  698. PrefabUtility.prefabInstanceUpdated += PrefabInstanceUpdated;
  699. EditorApplication.projectWasLoaded += OnProjectLoaded;
  700. AssetPreview.SetPreviewTextureCacheSize(256, GetInstanceID());
  701. wantsMouseMove = true;
  702. wantsMouseEnterLeaveWindow = true;
  703. if (m_PreviewResizer == null)
  704. {
  705. m_PreviewResizer = new PreviewResizer();
  706. m_PreviewResizer.Init("TilemapBrushInspector");
  707. }
  708. minSize = k_MinWindowSize;
  709. if (palette == null && !String.IsNullOrEmpty(lastTilemapPalette))
  710. {
  711. palette = GridPalettes.palettes
  712. .Where((palette, index) => (AssetDatabase.GetAssetPath(palette) == lastTilemapPalette))
  713. .FirstOrDefault();
  714. }
  715. if (palette == null && GridPalettes.palettes.Count > 0)
  716. {
  717. palette = GridPalettes.palettes[0];
  718. }
  719. ToolManager.activeToolChanged += ActiveToolChanged;
  720. ToolManager.activeToolChanging += ActiveToolChanging;
  721. ShortcutIntegration.instance.contextManager.RegisterToolContext(m_ShortcutContext);
  722. }
  723. private static void UpdateTooltips(IShortcutProfileManager obj, Identifier identifier, ShortcutBinding oldBinding, ShortcutBinding newBinding)
  724. {
  725. TilemapEditorTool.UpdateTooltips();
  726. }
  727. private void PrefabInstanceUpdated(GameObject updatedPrefab)
  728. {
  729. // case 947462: Reset the palette instance after its prefab has been updated as it could have been changed
  730. if (m_PaletteInstance != null && PrefabUtility.GetCorrespondingObjectFromSource(updatedPrefab) == m_Palette && !GridPaintingState.savingPalette)
  731. {
  732. ResetPreviewInstance();
  733. Repaint();
  734. }
  735. }
  736. private void OnProjectLoaded()
  737. {
  738. // ShortcutIntegration instance is recreated after LoadLayout which wipes the OnEnable registration
  739. ShortcutIntegration.instance.contextManager.RegisterToolContext(m_ShortcutContext);
  740. }
  741. private void OnBrushChanged(GridBrushBase brush)
  742. {
  743. DisableFocus();
  744. if (brush is GridBrush)
  745. EnableFocus();
  746. SceneView.RepaintAll();
  747. }
  748. private void OnGridSelectionChanged()
  749. {
  750. Repaint();
  751. }
  752. public void OnDisable()
  753. {
  754. m_Enabled = false;
  755. DisableFocus();
  756. focusMode = TilemapFocusMode.None;
  757. CallOnToolDeactivated();
  758. instances.Remove(this);
  759. if (instances.Count <= 1)
  760. GridPaintingState.gridBrush = null;
  761. DestroyPreviewInstance();
  762. DestroyImmediate(clipboardView);
  763. DestroyImmediate(m_PaintableSceneViewGrid);
  764. if (m_PreviewUtility != null)
  765. m_PreviewUtility.Cleanup();
  766. m_PreviewUtility = null;
  767. if (PaintableGrid.InGridEditMode())
  768. {
  769. // Set Editor Tool to an always available Tool, as Tile Palette Tools are not available any more
  770. ToolManager.SetActiveTool<UnityEditor.RectTool>();
  771. }
  772. ShortcutIntegration.instance.profileManager.shortcutBindingChanged -= UpdateTooltips;
  773. ToolManager.activeToolChanged -= ActiveToolChanged;
  774. ToolManager.activeToolChanging -= ActiveToolChanging;
  775. GridSelection.gridSelectionChanged -= OnGridSelectionChanged;
  776. SceneView.duringSceneGui -= OnSceneViewGUI;
  777. GridPaintingState.scenePaintTargetChanged -= OnScenePaintTargetChanged;
  778. GridPaintingState.brushChanged -= OnBrushChanged;
  779. GridPaintingState.UnregisterPainterInterest(this);
  780. PrefabUtility.prefabInstanceUpdated -= PrefabInstanceUpdated;
  781. EditorApplication.projectWasLoaded -= OnProjectLoaded;
  782. ShortcutIntegration.instance.contextManager.DeregisterToolContext(m_ShortcutContext);
  783. }
  784. private void OnScenePaintTargetChanged(GameObject scenePaintTarget)
  785. {
  786. DisableFocus();
  787. EnableFocus();
  788. Repaint();
  789. }
  790. private void ActiveToolChanged()
  791. {
  792. if (GridPaintingState.gridBrush != null && PaintableGrid.InGridEditMode() && GridPaintingState.activeBrushEditor != null)
  793. {
  794. GridBrushBase.Tool tool = PaintableGrid.EditTypeToBrushTool(ToolManager.activeToolType);
  795. GridPaintingState.activeBrushEditor.OnToolActivated(tool);
  796. m_PreviousToolActivatedEditor = GridPaintingState.activeBrushEditor;
  797. m_PreviousToolActivated = tool;
  798. for (int i = 0; i < k_SceneViewEditModes.Length; ++i)
  799. {
  800. if (k_SceneViewEditModes[i] == tool)
  801. {
  802. Cursor.SetCursor(MouseStyles.mouseCursorTextures[i],
  803. MouseStyles.mouseCursorTextures[i] != null ? MouseStyles.mouseCursorOSHotspot[(int)SystemInfo.operatingSystemFamily] : Vector2.zero,
  804. CursorMode.Auto);
  805. break;
  806. }
  807. }
  808. }
  809. else
  810. {
  811. Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
  812. }
  813. Repaint();
  814. }
  815. private void ActiveToolChanging()
  816. {
  817. if (!TilemapEditorTool.IsActive(typeof(MoveTool)) && !TilemapEditorTool.IsActive(typeof(SelectTool)))
  818. {
  819. GridSelection.Clear();
  820. }
  821. CallOnToolDeactivated();
  822. }
  823. private void CallOnToolDeactivated()
  824. {
  825. if (GridPaintingState.gridBrush != null && m_PreviousToolActivatedEditor != null)
  826. {
  827. m_PreviousToolActivatedEditor.OnToolDeactivated(m_PreviousToolActivated);
  828. m_PreviousToolActivatedEditor = null;
  829. if (!PaintableGrid.InGridEditMode())
  830. Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
  831. }
  832. }
  833. internal void ResetZPosition()
  834. {
  835. GridPaintingState.gridBrush.ResetZPosition();
  836. GridPaintingState.lastActiveGrid.ResetZPosition();
  837. }
  838. private void OnBrushInspectorGUI()
  839. {
  840. if (GridPaintingState.gridBrush == null)
  841. return;
  842. // Brush Inspector GUI
  843. EditorGUI.BeginChangeCheck();
  844. if (GridPaintingState.activeBrushEditor != null)
  845. GridPaintingState.activeBrushEditor.OnPaintInspectorGUI();
  846. else if (GridPaintingState.fallbackEditor != null)
  847. GridPaintingState.fallbackEditor.OnInspectorGUI();
  848. if (EditorGUI.EndChangeCheck())
  849. {
  850. GridPaletteBrushes.ActiveGridBrushAssetChanged();
  851. }
  852. // Z Position Inspector
  853. var hasLastActiveGrid = GridPaintingState.lastActiveGrid != null;
  854. using (new EditorGUI.DisabledScope(!hasLastActiveGrid))
  855. {
  856. var lockZPosition = false;
  857. if (GridPaintingState.activeBrushEditor != null)
  858. {
  859. EditorGUI.BeginChangeCheck();
  860. lockZPosition = EditorGUILayout.Toggle(Styles.lockZPosition, !GridPaintingState.activeBrushEditor.canChangeZPosition);
  861. if (EditorGUI.EndChangeCheck())
  862. GridPaintingState.activeBrushEditor.canChangeZPosition = !lockZPosition;
  863. }
  864. using (new EditorGUI.DisabledScope(lockZPosition))
  865. {
  866. EditorGUILayout.BeginHorizontal();
  867. EditorGUI.BeginChangeCheck();
  868. var zPosition = EditorGUILayout.DelayedIntField(Styles.zPosition, hasLastActiveGrid ? GridPaintingState.lastActiveGrid.zPosition : 0);
  869. if (EditorGUI.EndChangeCheck())
  870. {
  871. GridPaintingState.gridBrush.ChangeZPosition(zPosition - GridPaintingState.lastActiveGrid.zPosition);
  872. GridPaintingState.lastActiveGrid.zPosition = zPosition;
  873. }
  874. if (GUILayout.Button(Styles.resetZPosition))
  875. {
  876. ResetZPosition();
  877. }
  878. EditorGUILayout.EndHorizontal();
  879. }
  880. }
  881. }
  882. private bool IsObjectPrefabInstance(Object target)
  883. {
  884. return target != null && PrefabUtility.IsPartOfRegularPrefab(target);
  885. }
  886. private GameObject FindPrefabInstanceEquivalent(GameObject prefabInstance, GameObject prefabTarget)
  887. {
  888. var prefabRoot = prefabTarget.transform.root.gameObject;
  889. var currentTransform = prefabTarget.transform;
  890. var reverseTransformOrder = new Stack<int>();
  891. while (currentTransform != prefabRoot.transform && currentTransform.parent != null)
  892. {
  893. var parentTransform = currentTransform.parent;
  894. for (int i = 0; i < parentTransform.childCount; ++i)
  895. {
  896. if (currentTransform == parentTransform.GetChild(i))
  897. {
  898. reverseTransformOrder.Push(i);
  899. break;
  900. }
  901. }
  902. currentTransform = currentTransform.parent;
  903. }
  904. currentTransform = prefabInstance.transform;
  905. while (reverseTransformOrder.Count > 0)
  906. {
  907. var childIndex = reverseTransformOrder.Pop();
  908. if (childIndex >= currentTransform.childCount)
  909. return null;
  910. currentTransform = currentTransform.GetChild(childIndex);
  911. }
  912. return currentTransform.gameObject;
  913. }
  914. private void GoToPrefabMode(GameObject target)
  915. {
  916. var prefabObject = PrefabUtility.GetCorrespondingObjectFromSource(target);
  917. var assetPath = AssetDatabase.GetAssetPath(prefabObject);
  918. var stage = PrefabStageUtility.OpenPrefab(assetPath);
  919. var prefabInstance = stage.prefabContentsRoot;
  920. var prefabTarget = FindPrefabInstanceEquivalent(prefabInstance, prefabObject);
  921. if (prefabTarget != null)
  922. {
  923. GridPaintingState.scenePaintTarget = prefabTarget;
  924. }
  925. }
  926. private void DoActiveTargetsGUI()
  927. {
  928. using (new EditorGUI.DisabledScope(GridPaintingState.validTargets == null || GridPaintingState.scenePaintTarget == null))
  929. {
  930. bool hasPaintTarget = GridPaintingState.scenePaintTarget != null;
  931. bool needWarning = IsObjectPrefabInstance(GridPaintingState.scenePaintTarget);
  932. GUILayout.Label(Styles.activeTargetLabel, GUILayout.Width(k_ActiveTargetLabelWidth), GUILayout.Height(k_ActiveTargetWarningSize));
  933. GUIContent content = GUIContent.Temp(hasPaintTarget ? GridPaintingState.scenePaintTarget.name : "Nothing");
  934. if (EditorGUILayout.DropdownButton(content, FocusType.Passive, EditorStyles.popup, GUILayout.Width(k_ActiveTargetDropdownWidth - (needWarning ? k_ActiveTargetWarningSize : 0f)), GUILayout.Height(k_ActiveTargetWarningSize)))
  935. {
  936. int index = hasPaintTarget ? Array.IndexOf(GridPaintingState.validTargets, GridPaintingState.scenePaintTarget) : 0;
  937. var menuData = new GridPaintTargetsDropdown.MenuItemProvider();
  938. var flexibleMenu = new GridPaintTargetsDropdown(menuData, index, null, SelectTarget, k_ActiveTargetDropdownWidth);
  939. PopupWindow.Show(GUILayoutUtility.topLevel.GetLast(), flexibleMenu);
  940. }
  941. if (needWarning)
  942. GUILayout.Label(Styles.prefabWarningIcon, GUILayout.Width(k_ActiveTargetWarningSize), GUILayout.Height(k_ActiveTargetWarningSize));
  943. }
  944. }
  945. private void SelectTarget(int i, object o)
  946. {
  947. var obj = o as GameObject;
  948. var isPrefabInstance = IsObjectPrefabInstance(obj);
  949. if (isPrefabInstance)
  950. {
  951. var editMode = (TilePaletteProperties.PrefabEditModeSettings)EditorPrefs.GetInt(TilePaletteProperties.targetEditModeEditorPref, 0);
  952. switch (editMode)
  953. {
  954. case TilePaletteProperties.PrefabEditModeSettings.EnableDialog:
  955. {
  956. var option = EditorUtility.DisplayDialogComplex(TilePaletteProperties.targetEditModeDialogTitle
  957. , TilePaletteProperties.targetEditModeDialogMessage
  958. , TilePaletteProperties.targetEditModeDialogYes
  959. , TilePaletteProperties.targetEditModeDialogNo
  960. , TilePaletteProperties.targetEditModeDialogChange);
  961. switch (option)
  962. {
  963. case 0:
  964. GoToPrefabMode(obj);
  965. return;
  966. case 1:
  967. // Do nothing here for "No"
  968. break;
  969. case 2:
  970. var settingsWindow = SettingsWindow.Show(SettingsScope.User);
  971. settingsWindow.FilterProviders(TilePaletteProperties.targetEditModeLookup);
  972. break;
  973. }
  974. }
  975. break;
  976. case TilePaletteProperties.PrefabEditModeSettings.EditInPrefabMode:
  977. GoToPrefabMode(obj);
  978. return;
  979. case TilePaletteProperties.PrefabEditModeSettings.EditInScene:
  980. default:
  981. break;
  982. }
  983. }
  984. GridPaintingState.scenePaintTarget = obj;
  985. if (GridPaintingState.scenePaintTarget != null)
  986. EditorGUIUtility.PingObject(GridPaintingState.scenePaintTarget);
  987. }
  988. private void DoClipboardHeader()
  989. {
  990. if (!GridPalettes.palettes.Contains(palette) || palette == null) // Palette not in list means it was deleted
  991. {
  992. GridPalettes.CleanCache();
  993. if (GridPalettes.palettes.Count > 0)
  994. {
  995. palette = GridPalettes.palettes.LastOrDefault();
  996. }
  997. }
  998. EditorGUILayout.BeginHorizontal();
  999. DoPalettesDropdown();
  1000. using (new EditorGUI.DisabledScope(palette == null))
  1001. {
  1002. clipboardView.unlocked = GUILayout.Toggle(clipboardView.unlocked,
  1003. clipboardView.isModified ? Styles.editModified : Styles.edit,
  1004. EditorStyles.toolbarButton);
  1005. }
  1006. GUILayout.FlexibleSpace();
  1007. using (new EditorGUI.DisabledScope(palette == null))
  1008. {
  1009. EditorGUI.BeginChangeCheck();
  1010. m_DrawGridGizmo = GUILayout.Toggle(m_DrawGridGizmo, Styles.gridGizmo, EditorStyles.toolbarButton);
  1011. EditorGUI.BeginChangeCheck();
  1012. m_DrawGizmos = GUILayout.Toggle(m_DrawGizmos, Styles.gizmos, EditorStyles.toolbarButton);
  1013. if (EditorGUI.EndChangeCheck() && m_DrawGizmos)
  1014. {
  1015. clipboardView.SavePaletteIfNecessary();
  1016. ResetPreviewInstance();
  1017. }
  1018. if (EditorGUI.EndChangeCheck())
  1019. {
  1020. // Repaint if either option changes
  1021. Repaint();
  1022. }
  1023. }
  1024. EditorGUILayout.EndHorizontal();
  1025. }
  1026. private void DoPalettesDropdown()
  1027. {
  1028. string name = palette != null ? palette.name : Styles.createNewPalette.text;
  1029. Rect rect = GUILayoutUtility.GetRect(GUIContent.Temp(name), EditorStyles.toolbarDropDown, Styles.dropdownOptions);
  1030. if (GridPalettes.palettes.Count == 0)
  1031. {
  1032. if (EditorGUI.DropdownButton(rect, GUIContent.Temp(name), FocusType.Passive, EditorStyles.toolbarDropDown))
  1033. {
  1034. OpenAddPalettePopup(rect);
  1035. }
  1036. }
  1037. else
  1038. {
  1039. GUIContent content = GUIContent.Temp(GridPalettes.palettes.Count > 0 && palette != null ? palette.name : Styles.createNewPalette.text);
  1040. if (EditorGUI.DropdownButton(rect, content, FocusType.Passive, EditorStyles.toolbarPopup))
  1041. {
  1042. var menuData = new GridPalettesDropdown.MenuItemProvider();
  1043. m_PaletteDropdown = new GridPalettesDropdown(menuData, GridPalettes.palettes.IndexOf(palette), null, SelectPalette, k_DropdownWidth);
  1044. PopupWindow.Show(GUILayoutUtility.topLevel.GetLast(), m_PaletteDropdown);
  1045. }
  1046. }
  1047. }
  1048. private void SelectPalette(int i, object o)
  1049. {
  1050. if (i < GridPalettes.palettes.Count)
  1051. {
  1052. palette = GridPalettes.palettes[i];
  1053. }
  1054. else
  1055. {
  1056. m_PaletteDropdown.editorWindow.Close();
  1057. OpenAddPalettePopup(new Rect(0, 0, 0, 0));
  1058. }
  1059. }
  1060. private void OpenAddPalettePopup(Rect rect)
  1061. {
  1062. bool popupOpened = GridPaletteAddPopup.ShowAtPosition(rect, this);
  1063. if (popupOpened)
  1064. GUIUtility.ExitGUI();
  1065. }
  1066. private void DisplayClipboardText(GUIContent clipboardText, Rect position)
  1067. {
  1068. Color old = GUI.color;
  1069. GUI.color = Color.gray;
  1070. var infoSize = GUI.skin.label.CalcSize(clipboardText);
  1071. Rect rect = new Rect(position.center.x - infoSize.x * .5f, position.center.y - infoSize.y, 500, 100);
  1072. GUI.Label(rect, clipboardText);
  1073. GUI.color = old;
  1074. }
  1075. private void OnClipboardGUI(Rect position)
  1076. {
  1077. if (Event.current.type != EventType.Layout && position.Contains(Event.current.mousePosition) && GridPaintingState.activeGrid != clipboardView && clipboardView.unlocked)
  1078. {
  1079. GridPaintingState.activeGrid = clipboardView;
  1080. SceneView.RepaintAll();
  1081. }
  1082. // Validate palette (case 1017965)
  1083. GUIContent paletteError = null;
  1084. if (palette == null)
  1085. {
  1086. if (GridPalettes.palettes.Count == 0)
  1087. paletteError = Styles.emptyProjectInfo;
  1088. else
  1089. paletteError = Styles.invalidPaletteInfo;
  1090. }
  1091. else if (palette.GetComponent<Grid>() == null)
  1092. {
  1093. paletteError = Styles.invalidGridInfo;
  1094. }
  1095. if (paletteError != null)
  1096. {
  1097. DisplayClipboardText(paletteError, position);
  1098. return;
  1099. }
  1100. bool oldEnabled = GUI.enabled;
  1101. GUI.enabled = !clipboardView.showNewEmptyClipboardInfo || DragAndDrop.objectReferences.Length > 0;
  1102. if (Event.current.type == EventType.Repaint)
  1103. clipboardView.guiRect = position;
  1104. if (m_DelayedResetPaletteInstance)
  1105. ResetPreviewInstance();
  1106. EditorGUI.BeginChangeCheck();
  1107. clipboardView.OnGUI();
  1108. if (EditorGUI.EndChangeCheck())
  1109. Repaint();
  1110. GUI.enabled = oldEnabled;
  1111. if (clipboardView.showNewEmptyClipboardInfo)
  1112. {
  1113. DisplayClipboardText(Styles.emptyPaletteInfo, position);
  1114. }
  1115. }
  1116. private void ConvertGridPrefabToPalette(Rect targetPosition)
  1117. {
  1118. if (!targetPosition.Contains(Event.current.mousePosition)
  1119. || (Event.current.type != EventType.DragPerform
  1120. && Event.current.type != EventType.DragUpdated)
  1121. || DragAndDrop.objectReferences.Length != 1)
  1122. return;
  1123. var draggedObject = DragAndDrop.objectReferences[0];
  1124. if (!PrefabUtility.IsPartOfRegularPrefab(draggedObject))
  1125. return;
  1126. switch (Event.current.type)
  1127. {
  1128. case EventType.DragUpdated:
  1129. {
  1130. DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
  1131. Event.current.Use();
  1132. GUI.changed = true;
  1133. }
  1134. break;
  1135. case EventType.DragPerform:
  1136. {
  1137. var path = AssetDatabase.GetAssetPath(draggedObject);
  1138. var assets = AssetDatabase.LoadAllAssetsAtPath(path);
  1139. bool hasNewPaletteAsset = false;
  1140. Grid gridPrefab = null;
  1141. foreach (var asset in assets)
  1142. {
  1143. var gridPalette = asset as GridPalette;
  1144. hasNewPaletteAsset |= gridPalette != null;
  1145. GameObject go = asset as GameObject;
  1146. if (go != null)
  1147. {
  1148. var grid = go.GetComponent<Grid>();
  1149. if (grid != null)
  1150. gridPrefab = grid;
  1151. }
  1152. }
  1153. if (!hasNewPaletteAsset && gridPrefab != null)
  1154. {
  1155. var cellLayout = gridPrefab.cellLayout;
  1156. var cellSizing = (cellLayout == GridLayout.CellLayout.Rectangle
  1157. || cellLayout == GridLayout.CellLayout.Hexagon)
  1158. ? GridPalette.CellSizing.Automatic
  1159. : GridPalette.CellSizing.Manual;
  1160. var newPalette = GridPaletteUtility.CreateGridPalette(cellSizing);
  1161. AssetDatabase.AddObjectToAsset(newPalette, path);
  1162. AssetDatabase.ForceReserializeAssets(new string[] {path});
  1163. AssetDatabase.SaveAssets();
  1164. Event.current.Use();
  1165. GUIUtility.ExitGUI();
  1166. }
  1167. }
  1168. break;
  1169. }
  1170. }
  1171. private void OnSceneViewGUI(SceneView sceneView)
  1172. {
  1173. if ((GridPaintingState.defaultBrush == null || GridPaintingState.scenePaintTarget == null) && focusMode != TilemapFocusMode.None)
  1174. {
  1175. // case 946284: Disable Focus if focus mode is set but there is nothing to focus on
  1176. DisableFocus();
  1177. focusMode = TilemapFocusMode.None;
  1178. }
  1179. }
  1180. internal void SetFocusMode(TilemapFocusMode tilemapFocusMode)
  1181. {
  1182. if (tilemapFocusMode != focusMode)
  1183. {
  1184. DisableFocus();
  1185. focusMode = tilemapFocusMode;
  1186. EnableFocus();
  1187. }
  1188. }
  1189. private void FilterSingleSceneObjectInScene(int instanceID)
  1190. {
  1191. if (SceneView.lastActiveSceneView != null)
  1192. SceneView.lastActiveSceneView.SetSceneViewFiltering(true);
  1193. StageHandle currentStageHandle = StageUtility.GetCurrentStageHandle();
  1194. if (currentStageHandle.IsValid() && !currentStageHandle.isMainStage)
  1195. {
  1196. HierarchyProperty.FilterSingleSceneObjectInScene(instanceID
  1197. , false
  1198. , new UnityEngine.SceneManagement.Scene[] { currentStageHandle.customScene });
  1199. }
  1200. else
  1201. {
  1202. HierarchyProperty.FilterSingleSceneObject(instanceID, false);
  1203. }
  1204. if (SceneView.lastActiveSceneView != null)
  1205. SceneView.lastActiveSceneView.Repaint();
  1206. }
  1207. private void EnableFocus()
  1208. {
  1209. if (GridPaintingState.scenePaintTarget == null)
  1210. return;
  1211. switch (focusMode)
  1212. {
  1213. case TilemapFocusMode.Tilemap:
  1214. {
  1215. FilterSingleSceneObjectInScene(GridPaintingState.scenePaintTarget.GetInstanceID());
  1216. break;
  1217. }
  1218. case TilemapFocusMode.Grid:
  1219. {
  1220. Tilemap tilemap = GridPaintingState.scenePaintTarget.GetComponent<Tilemap>();
  1221. if (tilemap != null && tilemap.layoutGrid != null)
  1222. {
  1223. FilterSingleSceneObjectInScene(tilemap.layoutGrid.gameObject.GetInstanceID());
  1224. }
  1225. break;
  1226. }
  1227. }
  1228. }
  1229. private void DisableFocus()
  1230. {
  1231. if (focusMode == TilemapFocusMode.None)
  1232. return;
  1233. StageHandle currentStageHandle = StageUtility.GetCurrentStageHandle();
  1234. if (currentStageHandle.IsValid() && !currentStageHandle.isMainStage)
  1235. {
  1236. HierarchyProperty.ClearSceneObjectsFilterInScene(new UnityEngine.SceneManagement.Scene[] { currentStageHandle.customScene });
  1237. }
  1238. else
  1239. {
  1240. HierarchyProperty.ClearSceneObjectsFilter();
  1241. }
  1242. if (SceneView.lastActiveSceneView != null)
  1243. {
  1244. SceneView.lastActiveSceneView.SetSceneViewFiltering(false);
  1245. SceneView.lastActiveSceneView.Repaint();
  1246. }
  1247. }
  1248. [MenuItem("Window/2D/Tile Palette", false, 2)]
  1249. public static void OpenTilemapPalette()
  1250. {
  1251. GridPaintPaletteWindow w = GetWindow<GridPaintPaletteWindow>();
  1252. w.titleContent = Styles.tilePalette;
  1253. }
  1254. // TODO: Better way of clearing caches than AssetPostprocessor
  1255. public class AssetProcessor : AssetPostprocessor
  1256. {
  1257. public override int GetPostprocessOrder()
  1258. {
  1259. return int.MaxValue;
  1260. }
  1261. private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromPath)
  1262. {
  1263. if (GridPaintingState.savingPalette)
  1264. return;
  1265. foreach (var window in instances)
  1266. {
  1267. window.DelayedResetPreviewInstance();
  1268. }
  1269. }
  1270. }
  1271. public class PaletteAssetModificationProcessor : AssetModificationProcessor
  1272. {
  1273. static void OnWillCreateAsset(string assetName)
  1274. {
  1275. SavePalettesIfRequired(null);
  1276. }
  1277. static string[] OnWillSaveAssets(string[] paths)
  1278. {
  1279. SavePalettesIfRequired(paths);
  1280. return paths;
  1281. }
  1282. static void SavePalettesIfRequired(string[] paths)
  1283. {
  1284. if (GridPaintingState.savingPalette)
  1285. return;
  1286. foreach (var window in instances)
  1287. {
  1288. if (window.clipboardView.isModified)
  1289. {
  1290. window.clipboardView.CheckRevertIfChanged(paths);
  1291. window.clipboardView.SavePaletteIfNecessary();
  1292. window.Repaint();
  1293. }
  1294. }
  1295. }
  1296. }
  1297. }
  1298. }