2022-01-12 10:39:15 +03:00
using System ;
2022-01-12 10:06:03 +03:00
using System.Collections.Generic ;
using System.Linq ;
using UnityEditor.EditorTools ;
using UnityEditor.ShortcutManagement ;
using UnityEngine ;
using UnityEngine.Tilemaps ;
using Event = UnityEngine . Event ;
using Object = UnityEngine . Object ;
using UnityEditor.Experimental.SceneManagement ;
2022-01-12 10:39:15 +03:00
using UnityEditor.SceneManagement ;
2022-01-12 10:06:03 +03:00
namespace UnityEditor.Tilemaps
{
internal class GridPaintPaletteWindow : EditorWindow
{
2022-01-12 10:39:15 +03:00
internal enum TilemapFocusMode
2022-01-12 10:06:03 +03:00
{
None = 0 ,
Tilemap = 1 ,
Grid = 2
}
private static readonly string k_TilemapFocusModeEditorPref = "TilemapFocusMode" ;
private TilemapFocusMode focusMode
{
get
{
return ( TilemapFocusMode ) EditorPrefs . GetInt ( k_TilemapFocusModeEditorPref , ( int ) TilemapFocusMode . None ) ;
}
set
{
EditorPrefs . SetInt ( k_TilemapFocusModeEditorPref , ( int ) value ) ;
}
}
private static readonly string k_TilemapLastPaletteEditorPref = "TilemapLastPalette" ;
private string lastTilemapPalette
{
get
{
return EditorPrefs . GetString ( k_TilemapLastPaletteEditorPref , "" ) ;
}
set
{
EditorPrefs . SetString ( k_TilemapLastPaletteEditorPref , value ) ;
}
}
private static class MouseStyles
{
// The following paths match the enums in OperatingSystemFamily
public static readonly string [ ] mouseCursorOSPath =
{
"" , // Other OS
"Cursors/macOS" ,
"Cursors/Windows" ,
"Cursors/Linux" ,
} ;
// The following paths match the enums in OperatingSystemFamily
public static readonly Vector2 [ ] mouseCursorOSHotspot =
{
Vector2 . zero , // Other OS
new Vector2 ( 6f , 4f ) ,
new Vector2 ( 6f , 4f ) ,
new Vector2 ( 6f , 4f ) ,
} ;
// The following paths match the enums in sceneViewEditModes above
public static readonly string [ ] mouseCursorTexturePaths =
{
"" ,
"Grid.MoveTool.png" ,
"Grid.PaintTool.png" ,
"Grid.BoxTool.png" ,
"Grid.PickingTool.png" ,
"Grid.EraserTool.png" ,
"Grid.FillTool.png" ,
} ;
public static readonly Texture2D [ ] mouseCursorTextures ;
static MouseStyles ( )
{
mouseCursorTextures = new Texture2D [ mouseCursorTexturePaths . Length ] ;
int osIndex = ( int ) SystemInfo . operatingSystemFamily ;
for ( int i = 0 ; i < mouseCursorTexturePaths . Length ; + + i )
{
if ( ( mouseCursorOSPath [ osIndex ] ! = null & & mouseCursorOSPath [ osIndex ] . Length > 0 )
& & ( mouseCursorTexturePaths [ i ] ! = null & & mouseCursorTexturePaths [ i ] . Length > 0 ) )
{
string cursorPath = Utils . Paths . Combine ( mouseCursorOSPath [ osIndex ] , mouseCursorTexturePaths [ i ] ) ;
mouseCursorTextures [ i ] = EditorGUIUtility . LoadRequired ( cursorPath ) as Texture2D ;
}
else
mouseCursorTextures [ i ] = null ;
}
}
}
private static class Styles
{
public static readonly GUIContent emptyProjectInfo = EditorGUIUtility . TrTextContent ( "Create a new palette in the dropdown above." ) ;
public static readonly GUIContent emptyPaletteInfo = EditorGUIUtility . TrTextContent ( "Drag Tile, Sprite or Sprite Texture assets here." ) ;
public static readonly GUIContent invalidPaletteInfo = EditorGUIUtility . TrTextContent ( "This is an invalid palette. Did you delete the palette asset?" ) ;
public static readonly GUIContent invalidGridInfo = EditorGUIUtility . TrTextContent ( "The palette has an invalid Grid. Did you add a Grid to the palette asset?" ) ;
public static readonly GUIContent selectPaintTarget = EditorGUIUtility . TrTextContent ( "Select Paint Target" ) ;
public static readonly GUIContent selectPalettePrefab = EditorGUIUtility . TrTextContent ( "Select Palette Prefab" ) ;
public static readonly GUIContent selectTileAsset = EditorGUIUtility . TrTextContent ( "Select Tile Asset" ) ;
public static readonly GUIContent unlockPaletteEditing = EditorGUIUtility . TrTextContent ( "Unlock Palette Editing" ) ;
public static readonly GUIContent lockPaletteEditing = EditorGUIUtility . TrTextContent ( "Lock Palette Editing" ) ;
2022-01-12 10:39:15 +03:00
public static readonly GUIContent openTilePalettePreferences = EditorGUIUtility . TrTextContent ( "Open Tile Palette Preferences" ) ;
2022-01-12 10:06:03 +03:00
public static readonly GUIContent createNewPalette = EditorGUIUtility . TrTextContent ( "Create New Palette" ) ;
public static readonly GUIContent focusLabel = EditorGUIUtility . TrTextContent ( "Focus On" ) ;
public static readonly GUIContent rendererOverlayTitleLabel = EditorGUIUtility . TrTextContent ( "Tilemap" ) ;
public static readonly GUIContent activeTargetLabel = EditorGUIUtility . TrTextContent ( "Active Tilemap" , "Specifies the currently active Tilemap used for painting in the Scene View." ) ;
public static readonly GUIContent prefabWarningIcon = EditorGUIUtility . TrIconContent ( "console.warnicon.sml" , "Editing Tilemaps in Prefabs will have better performance if edited in Prefab Mode." ) ;
public static readonly GUIContent tilePalette = EditorGUIUtility . TrTextContent ( "Tile Palette" ) ;
2022-01-12 10:39:15 +03:00
public static readonly GUIContent edit = EditorGUIUtility . TrTextContent ( "Edit" , "Toggle to edit current Tile Palette" ) ;
public static readonly GUIContent editModified = EditorGUIUtility . TrTextContent ( "Edit*" , "Toggle to save edits for current Tile Palette" ) ;
public static readonly GUIContent gizmos = EditorGUIUtility . TrTextContent ( "Gizmos" , "Toggle visibility of Gizmos in the Tile Palette" ) ;
public static readonly GUIContent lockZPosition = EditorGUIUtility . TrTextContent ( "Lock Z Position" , "Toggle editing of Z position" ) ;
public static readonly GUIContent zPosition = EditorGUIUtility . TrTextContent ( "Z Position" , "Set a Z position for the active Brush for painting" ) ;
public static readonly GUIContent resetZPosition = EditorGUIUtility . TrTextContent ( "Reset" , "Reset Z position for the active Brush" ) ;
2022-01-12 10:06:03 +03:00
public static readonly GUIStyle ToolbarTitleStyle = "Toolbar" ;
public static readonly GUIStyle dragHandle = "RL DragHandle" ;
public static readonly float dragPadding = 3f ;
2022-01-12 10:39:15 +03:00
public static readonly GUILayoutOption [ ] dropdownOptions = { GUILayout . Width ( k_DropdownWidth ) } ;
}
private class TilePaletteSaveScope : IDisposable
{
private GameObject m_GameObject ;
public TilePaletteSaveScope ( GameObject paletteInstance )
{
m_GameObject = paletteInstance ;
if ( m_GameObject ! = null )
{
GridPaintingState . savingPalette = true ;
SetHideFlagsRecursively ( paletteInstance , HideFlags . HideInHierarchy ) ;
foreach ( var renderer in paletteInstance . GetComponentsInChildren < Renderer > ( ) )
renderer . gameObject . layer = 0 ;
}
}
public void Dispose ( )
{
if ( m_GameObject ! = null )
{
SetHideFlagsRecursively ( m_GameObject , HideFlags . HideAndDontSave ) ;
GridPaintingState . savingPalette = false ;
}
}
private void SetHideFlagsRecursively ( GameObject root , HideFlags flags )
{
root . hideFlags = flags ;
for ( int i = 0 ; i < root . transform . childCount ; i + + )
SetHideFlagsRecursively ( root . transform . GetChild ( i ) . gameObject , flags ) ;
}
2022-01-12 10:06:03 +03:00
}
internal class TilePaletteProperties
{
public enum PrefabEditModeSettings
{
EnableDialog = 0 ,
EditInPrefabMode = 1 ,
EditInScene = 2
}
public static readonly string targetEditModeDialogTitle = L10n . Tr ( "Open in Prefab Mode" ) ;
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?" ) ;
public static readonly string targetEditModeDialogYes = L10n . Tr ( "Prefab Mode" ) ;
public static readonly string targetEditModeDialogChange = L10n . Tr ( "Preferences" ) ;
public static readonly string targetEditModeDialogNo = L10n . Tr ( "Scene" ) ;
public static readonly string targetEditModeEditorPref = "TilePalette.TargetEditMode" ;
2022-01-12 10:39:15 +03:00
public static readonly string targetEditModeLookup = "Target Edit Mode" ;
public static readonly string tilePalettePreferencesLookup = "Tile Palette" ;
2022-01-12 10:06:03 +03:00
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" ) ;
}
private static readonly GridBrushBase . Tool [ ] k_SceneViewEditModes =
{
GridBrushBase . Tool . Select ,
GridBrushBase . Tool . Move ,
GridBrushBase . Tool . Paint ,
GridBrushBase . Tool . Box ,
GridBrushBase . Tool . Pick ,
GridBrushBase . Tool . Erase ,
GridBrushBase . Tool . FloodFill
} ;
private const float k_DropdownWidth = 200f ;
private const float k_ActiveTargetLabelWidth = 90f ;
private const float k_ActiveTargetDropdownWidth = 130f ;
private const float k_ActiveTargetWarningSize = 20f ;
2022-01-12 10:39:15 +03:00
private const float k_TopAreaHeight = 104f ;
2022-01-12 10:06:03 +03:00
private const float k_MinBrushInspectorHeight = 50f ;
private const float k_MinClipboardHeight = 200f ;
private const float k_ToolbarHeight = 17f ;
private const float k_ResizerDragRectPadding = 10f ;
private static readonly Vector2 k_MinWindowSize = new Vector2 ( k_ActiveTargetLabelWidth + k_ActiveTargetDropdownWidth + k_ActiveTargetWarningSize , 200f ) ;
private PaintableSceneViewGrid m_PaintableSceneViewGrid ;
class ShortcutContext : IShortcutToolContext
{
public bool active { get ; set ; }
}
2022-01-12 10:39:15 +03:00
readonly ShortcutContext m_ShortcutContext = new ShortcutContext { active = true } ;
2022-01-12 10:06:03 +03:00
[FormerlyPrefKeyAs("Grid Painting/Select", "s")]
[Shortcut("Grid Painting/Select", typeof(ShortcutContext), KeyCode.S)]
static void GridSelectKey ( )
{
TilemapEditorTool . ToggleActiveEditorTool ( typeof ( SelectTool ) ) ;
}
[FormerlyPrefKeyAs("Grid Painting/Move", "m")]
[Shortcut("Grid Painting/Move", typeof(ShortcutContext), KeyCode.M)]
static void GridMoveKey ( )
{
TilemapEditorTool . ToggleActiveEditorTool ( typeof ( MoveTool ) ) ;
}
[FormerlyPrefKeyAs("Grid Painting/Brush", "b")]
[Shortcut("Grid Painting/Brush", typeof(ShortcutContext), KeyCode.B)]
static void GridBrushKey ( )
{
TilemapEditorTool . ToggleActiveEditorTool ( typeof ( PaintTool ) ) ;
}
[FormerlyPrefKeyAs("Grid Painting/Rectangle", "u")]
[Shortcut("Grid Painting/Rectangle", typeof(ShortcutContext), KeyCode.U)]
static void GridRectangleKey ( )
{
TilemapEditorTool . ToggleActiveEditorTool ( typeof ( BoxTool ) ) ;
}
[FormerlyPrefKeyAs("Grid Painting/Picker", "i")]
[Shortcut("Grid Painting/Picker", typeof(ShortcutContext), KeyCode.I)]
static void GridPickerKey ( )
{
TilemapEditorTool . ToggleActiveEditorTool ( typeof ( PickingTool ) ) ;
}
[FormerlyPrefKeyAs("Grid Painting/Erase", "d")]
[Shortcut("Grid Painting/Erase", typeof(ShortcutContext), KeyCode.D)]
static void GridEraseKey ( )
{
TilemapEditorTool . ToggleActiveEditorTool ( typeof ( EraseTool ) ) ;
}
[FormerlyPrefKeyAs("Grid Painting/Fill", "g")]
[Shortcut("Grid Painting/Fill", typeof(ShortcutContext), KeyCode.G)]
static void GridFillKey ( )
{
TilemapEditorTool . ToggleActiveEditorTool ( typeof ( FillTool ) ) ;
}
static void RotateBrush ( GridBrushBase . RotationDirection direction )
{
GridPaintingState . gridBrush . Rotate ( direction , GridPaintingState . activeGrid . cellLayout ) ;
GridPaintingState . activeGrid . Repaint ( ) ;
}
[FormerlyPrefKeyAs("Grid Painting/Rotate Clockwise", "[")]
[Shortcut("Grid Painting/Rotate Clockwise", typeof(ShortcutContext), KeyCode.LeftBracket)]
static void RotateBrushClockwise ( )
{
if ( GridPaintingState . gridBrush ! = null & & GridPaintingState . activeGrid ! = null )
RotateBrush ( GridBrushBase . RotationDirection . Clockwise ) ;
}
[FormerlyPrefKeyAs("Grid Painting/Rotate Anti-Clockwise", "] ")]
[Shortcut("Grid Painting/Rotate Anti-Clockwise", typeof(ShortcutContext), KeyCode.RightBracket)]
static void RotateBrushAntiClockwise ( )
{
if ( GridPaintingState . gridBrush ! = null & & GridPaintingState . activeGrid ! = null )
RotateBrush ( GridBrushBase . RotationDirection . CounterClockwise ) ;
}
static void FlipBrush ( GridBrushBase . FlipAxis axis )
{
GridPaintingState . gridBrush . Flip ( axis , GridPaintingState . activeGrid . cellLayout ) ;
GridPaintingState . activeGrid . Repaint ( ) ;
}
[FormerlyPrefKeyAs("Grid Painting/Flip X", "#[")]
[Shortcut("Grid Painting/Flip X", typeof(ShortcutContext), KeyCode.LeftBracket, ShortcutModifiers.Shift)]
static void FlipBrushX ( )
{
if ( GridPaintingState . gridBrush ! = null & & GridPaintingState . activeGrid ! = null )
FlipBrush ( GridBrushBase . FlipAxis . X ) ;
}
[FormerlyPrefKeyAs("Grid Painting/Flip Y", "#] ")]
[Shortcut("Grid Painting/Flip Y", typeof(ShortcutContext), KeyCode.RightBracket, ShortcutModifiers.Shift)]
static void FlipBrushY ( )
{
if ( GridPaintingState . gridBrush ! = null & & GridPaintingState . activeGrid ! = null )
FlipBrush ( GridBrushBase . FlipAxis . Y ) ;
}
static void ChangeBrushZ ( int change )
{
GridPaintingState . gridBrush . ChangeZPosition ( change ) ;
GridPaintingState . activeGrid . ChangeZPosition ( change ) ;
GridPaintingState . activeGrid . Repaint ( ) ;
foreach ( var window in GridPaintPaletteWindow . instances )
{
window . Repaint ( ) ;
}
}
[Shortcut("Grid Painting/Increase Z", typeof(ShortcutContext), KeyCode.Minus)]
static void IncreaseBrushZ ( )
{
if ( GridPaintingState . gridBrush ! = null
& & GridPaintingState . activeGrid ! = null
& & GridPaintingState . activeBrushEditor ! = null
& & GridPaintingState . activeBrushEditor . canChangeZPosition )
ChangeBrushZ ( 1 ) ;
}
[Shortcut("Grid Painting/Decrease Z", typeof(ShortcutContext), KeyCode.Equals)]
static void DecreaseBrushZ ( )
{
if ( GridPaintingState . gridBrush ! = null
& & GridPaintingState . activeGrid ! = null
& & GridPaintingState . activeBrushEditor ! = null
& & GridPaintingState . activeBrushEditor . canChangeZPosition )
ChangeBrushZ ( - 1 ) ;
}
internal static void PreferencesGUI ( )
{
using ( new SettingsWindow . GUIScope ( ) )
{
EditorGUI . BeginChangeCheck ( ) ;
var val = ( TilePaletteProperties . PrefabEditModeSettings ) EditorGUILayout . EnumPopup ( TilePaletteProperties . targetEditModeDialogLabel , ( TilePaletteProperties . PrefabEditModeSettings ) EditorPrefs . GetInt ( TilePaletteProperties . targetEditModeEditorPref , 0 ) ) ;
if ( EditorGUI . EndChangeCheck ( ) )
{
EditorPrefs . SetInt ( TilePaletteProperties . targetEditModeEditorPref , ( int ) val ) ;
}
}
}
private static List < GridPaintPaletteWindow > s_Instances ;
public static List < GridPaintPaletteWindow > instances
{
get
{
if ( s_Instances = = null )
s_Instances = new List < GridPaintPaletteWindow > ( ) ;
return s_Instances ;
}
}
2022-01-12 10:39:15 +03:00
public static bool isActive
{
get
{
return s_Instances ! = null & & s_Instances . Count > 0 ;
}
}
2022-01-12 10:06:03 +03:00
[SerializeField]
private PreviewResizer m_PreviewResizer ;
private GridPalettesDropdown m_PaletteDropdown ;
[SerializeField]
private GameObject m_Palette ;
2022-01-12 10:39:15 +03:00
[SerializeField]
private bool m_DrawGizmos ;
internal bool drawGizmos
{
get { return m_DrawGizmos ; }
}
2022-01-12 10:06:03 +03:00
public GameObject palette
{
get
{
return m_Palette ;
}
set
{
if ( m_Palette ! = value )
{
clipboardView . OnBeforePaletteSelectionChanged ( ) ;
m_Palette = value ;
clipboardView . OnAfterPaletteSelectionChanged ( ) ;
lastTilemapPalette = AssetDatabase . GetAssetPath ( m_Palette ) ;
GridPaintingState . OnPaletteChanged ( m_Palette ) ;
Repaint ( ) ;
}
}
}
private GameObject m_PaletteInstance ;
public GameObject paletteInstance
{
get
{
return m_PaletteInstance ;
}
}
2022-01-12 10:39:15 +03:00
private bool m_DelayedResetPaletteInstance ;
private bool m_Enabled ;
2022-01-12 10:06:03 +03:00
public GridPaintPaletteClipboard clipboardView { get ; private set ; }
private Vector2 m_BrushScroll ;
private GridBrushEditorBase m_PreviousToolActivatedEditor ;
private GridBrushBase . Tool m_PreviousToolActivated ;
private PreviewRenderUtility m_PreviewUtility ;
public PreviewRenderUtility previewUtility
{
get
{
2022-01-12 10:39:15 +03:00
if ( m_Enabled & & m_PreviewUtility = = null )
2022-01-12 10:06:03 +03:00
InitPreviewUtility ( ) ;
return m_PreviewUtility ;
}
}
private void OnSelectionChange ( )
{
// Update active palette if user has selected a palette prefab
var selectedObject = Selection . activeGameObject ;
if ( selectedObject ! = null )
{
bool isPrefab = EditorUtility . IsPersistent ( selectedObject ) | | ( selectedObject . hideFlags & HideFlags . NotEditable ) ! = 0 ;
if ( isPrefab )
{
var assetPath = AssetDatabase . GetAssetPath ( selectedObject ) ;
var allAssets = AssetDatabase . LoadAllAssetRepresentationsAtPath ( assetPath ) ;
foreach ( var asset in allAssets )
{
if ( asset ! = null & & asset . GetType ( ) = = typeof ( GridPalette ) )
{
var targetPalette = ( GameObject ) AssetDatabase . LoadMainAssetAtPath ( assetPath ) ;
if ( targetPalette ! = palette )
{
palette = targetPalette ;
Repaint ( ) ;
}
break ;
}
}
}
}
}
private void OnGUI ( )
{
HandleContextMenu ( ) ;
EditorGUILayout . BeginVertical ( ) ;
GUILayout . Space ( 10f ) ;
EditorGUILayout . BeginHorizontal ( ) ;
float leftMargin = ( Screen . width / EditorGUIUtility . pixelsPerPoint - TilemapEditorTool . tilemapEditorToolsToolbarSize ) * 0.5f ;
GUILayout . Space ( leftMargin ) ;
DoTilemapToolbar ( ) ;
GUILayout . Space ( leftMargin ) ;
EditorGUILayout . EndHorizontal ( ) ;
EditorGUILayout . BeginHorizontal ( ) ;
GUILayout . Space ( leftMargin ) ;
DoActiveTargetsGUI ( ) ;
GUILayout . Space ( leftMargin ) ;
EditorGUILayout . EndHorizontal ( ) ;
GUILayout . Space ( 6f ) ;
EditorGUILayout . EndVertical ( ) ;
EditorGUILayout . BeginVertical ( ) ;
2022-01-12 10:39:15 +03:00
Rect clipboardToolbarRect = EditorGUILayout . BeginHorizontal ( GUIContent . none , Styles . ToolbarTitleStyle ) ;
2022-01-12 10:06:03 +03:00
DoClipboardHeader ( ) ;
EditorGUILayout . EndHorizontal ( ) ;
2022-01-12 10:39:15 +03:00
ConvertGridPrefabToPalette ( clipboardToolbarRect ) ;
2022-01-12 10:06:03 +03:00
Rect dragRect = new Rect ( k_DropdownWidth + k_ResizerDragRectPadding , 0 , position . width - k_DropdownWidth - k_ResizerDragRectPadding , k_ToolbarHeight ) ;
float brushInspectorSize = m_PreviewResizer . ResizeHandle ( position , k_MinBrushInspectorHeight , k_MinClipboardHeight , k_ToolbarHeight , dragRect ) ;
float clipboardHeight = position . height - brushInspectorSize - k_TopAreaHeight ;
Rect clipboardRect = new Rect ( 0f , clipboardToolbarRect . yMax , position . width , clipboardHeight ) ;
OnClipboardGUI ( clipboardRect ) ;
EditorGUILayout . EndVertical ( ) ;
GUILayout . Space ( clipboardRect . height ) ;
EditorGUILayout . BeginVertical ( ) ;
EditorGUILayout . BeginHorizontal ( GUIContent . none , Styles . ToolbarTitleStyle ) ;
DoBrushesDropdownToolbar ( ) ;
EditorGUILayout . EndHorizontal ( ) ;
m_BrushScroll = GUILayout . BeginScrollView ( m_BrushScroll , false , false ) ;
GUILayout . Space ( 4f ) ;
OnBrushInspectorGUI ( ) ;
GUILayout . EndScrollView ( ) ;
EditorGUILayout . EndVertical ( ) ;
Color oldColor = Handles . color ;
Handles . color = Color . black ;
Handles . DrawLine ( new Vector3 ( 0 , clipboardRect . yMax + 0.5f , 0 ) , new Vector3 ( Screen . width , clipboardRect . yMax + 0.5f , 0 ) ) ;
Handles . color = Color . black . AlphaMultiplied ( 0.33f ) ;
Handles . DrawLine ( new Vector3 ( 0 , GUILayoutUtility . GetLastRect ( ) . yMax + 0.5f , 0 ) , new Vector3 ( Screen . width , GUILayoutUtility . GetLastRect ( ) . yMax + 0.5f , 0 ) ) ;
Handles . color = oldColor ;
EditorGUILayout . BeginVertical ( ) ;
GUILayout . Space ( 2f ) ;
EditorGUILayout . EndVertical ( ) ;
// Keep repainting until all previews are loaded
if ( AssetPreview . IsLoadingAssetPreviews ( GetInstanceID ( ) ) )
Repaint ( ) ;
// Release keyboard focus on click to empty space
if ( Event . current . type = = EventType . MouseDown )
GUIUtility . keyboardControl = 0 ;
}
static void DoTilemapToolbar ( )
{
2022-01-12 10:39:15 +03:00
EditorTool active = EditorToolManager . activeTool ;
EditorTool selected ;
2022-01-12 10:06:03 +03:00
if ( EditorGUILayout . EditorToolbar ( active , TilemapEditorTool . tilemapEditorTools , out selected ) )
{
if ( active = = selected )
2022-01-12 10:39:15 +03:00
ToolManager . SetActiveTool ( EditorToolManager . GetLastTool ( x = > ! TilemapEditorTool . tilemapEditorTools . Contains ( x ) ) ) ;
2022-01-12 10:06:03 +03:00
else
2022-01-12 10:39:15 +03:00
ToolManager . SetActiveTool ( selected ) ;
2022-01-12 10:06:03 +03:00
}
}
2022-01-12 10:39:15 +03:00
public void DelayedResetPreviewInstance ( )
{
m_DelayedResetPaletteInstance = true ;
}
2022-01-12 10:06:03 +03:00
public void ResetPreviewInstance ( )
{
if ( m_PreviewUtility = = null )
InitPreviewUtility ( ) ;
2022-01-12 10:39:15 +03:00
m_DelayedResetPaletteInstance = false ;
2022-01-12 10:06:03 +03:00
DestroyPreviewInstance ( ) ;
if ( palette ! = null )
{
m_PaletteInstance = previewUtility . InstantiatePrefabInScene ( palette ) ;
// Disconnecting prefabs is no longer possible.
// If performance of overrides on palette palette instance turns out to be a problem.
// unpack the prefab instance here, and overwrite the prefab later instead of reconnecting.
2022-01-12 10:39:15 +03:00
PrefabUtility . UnpackPrefabInstance ( m_PaletteInstance , PrefabUnpackMode . OutermostRoot , InteractionMode . AutomatedAction ) ;
2022-01-12 10:06:03 +03:00
EditorUtility . InitInstantiatedPreviewRecursive ( m_PaletteInstance ) ;
m_PaletteInstance . transform . position = new Vector3 ( 0 , 0 , 0 ) ;
m_PaletteInstance . transform . rotation = Quaternion . identity ;
m_PaletteInstance . transform . localScale = Vector3 . one ;
2022-01-12 10:39:15 +03:00
GridPalette paletteAsset = GridPaletteUtility . GetGridPaletteFromPaletteAsset ( palette ) ;
2022-01-12 10:06:03 +03:00
if ( paletteAsset ! = null )
{
if ( paletteAsset . cellSizing = = GridPalette . CellSizing . Automatic )
{
Grid grid = m_PaletteInstance . GetComponent < Grid > ( ) ;
if ( grid ! = null )
{
grid . cellSize = GridPaletteUtility . CalculateAutoCellSize ( grid , grid . cellSize ) ;
}
else
{
2022-01-12 10:39:15 +03:00
Debug . LogWarning ( "Grid component not found from: " + palette . name ) ;
2022-01-12 10:06:03 +03:00
}
}
2022-01-12 10:39:15 +03:00
previewUtility . camera . transparencySortMode = paletteAsset . transparencySortMode ;
previewUtility . camera . transparencySortAxis = paletteAsset . transparencySortAxis ;
2022-01-12 10:06:03 +03:00
}
else
{
2022-01-12 10:39:15 +03:00
Debug . LogWarning ( "GridPalette subasset not found from: " + palette . name ) ;
previewUtility . camera . transparencySortMode = TransparencySortMode . Default ;
previewUtility . camera . transparencySortAxis = new Vector3 ( 0f , 0f , 1f ) ;
2022-01-12 10:06:03 +03:00
}
foreach ( var transform in m_PaletteInstance . GetComponentsInChildren < Transform > ( ) )
transform . gameObject . hideFlags = HideFlags . HideAndDontSave ;
2022-01-12 10:39:15 +03:00
// Show all renderers from Palettes from previous versions
PreviewRenderUtility . SetEnabledRecursive ( m_PaletteInstance , true ) ;
2022-01-12 10:06:03 +03:00
clipboardView . ResetPreviewMesh ( ) ;
}
}
public void DestroyPreviewInstance ( )
{
if ( m_PaletteInstance ! = null )
2022-01-12 10:39:15 +03:00
{
Undo . ClearUndo ( m_PaletteInstance ) ;
2022-01-12 10:06:03 +03:00
DestroyImmediate ( m_PaletteInstance ) ;
2022-01-12 10:39:15 +03:00
}
2022-01-12 10:06:03 +03:00
}
public void InitPreviewUtility ( )
{
2022-01-12 10:39:15 +03:00
int previewCullingLayer = Camera . PreviewCullingLayer ;
2022-01-12 10:06:03 +03:00
m_PreviewUtility = new PreviewRenderUtility ( true , true ) ;
2022-01-12 10:39:15 +03:00
m_PreviewUtility . camera . cullingMask = 1 < < previewCullingLayer ;
m_PreviewUtility . camera . gameObject . layer = previewCullingLayer ;
m_PreviewUtility . lights [ 0 ] . gameObject . layer = previewCullingLayer ;
2022-01-12 10:06:03 +03:00
m_PreviewUtility . camera . orthographic = true ;
m_PreviewUtility . camera . orthographicSize = 5f ;
m_PreviewUtility . camera . transform . position = new Vector3 ( 0f , 0f , - 10f ) ;
m_PreviewUtility . ambientColor = new Color ( 1f , 1f , 1f , 0 ) ;
ResetPreviewInstance ( ) ;
clipboardView . SetupPreviewCameraOnInit ( ) ;
}
private void HandleContextMenu ( )
{
if ( Event . current . type = = EventType . ContextClick )
{
DoContextMenu ( ) ;
Event . current . Use ( ) ;
}
}
public void SavePalette ( )
{
if ( paletteInstance ! = null & & palette ! = null )
{
2022-01-12 10:39:15 +03:00
using ( new TilePaletteSaveScope ( paletteInstance ) )
{
string path = AssetDatabase . GetAssetPath ( palette ) ;
PrefabUtility . SaveAsPrefabAssetAndConnect ( paletteInstance , path , InteractionMode . AutomatedAction ) ;
}
2022-01-12 10:06:03 +03:00
2022-01-12 10:39:15 +03:00
ResetPreviewInstance ( ) ;
Repaint ( ) ;
2022-01-12 10:06:03 +03:00
}
}
private void DoContextMenu ( )
{
GenericMenu pm = new GenericMenu ( ) ;
if ( GridPaintingState . scenePaintTarget ! = null )
pm . AddItem ( Styles . selectPaintTarget , false , SelectPaintTarget ) ;
else
pm . AddDisabledItem ( Styles . selectPaintTarget ) ;
if ( palette ! = null )
pm . AddItem ( Styles . selectPalettePrefab , false , SelectPaletteAsset ) ;
else
pm . AddDisabledItem ( Styles . selectPalettePrefab ) ;
if ( clipboardView . activeTile ! = null )
pm . AddItem ( Styles . selectTileAsset , false , SelectTileAsset ) ;
else
pm . AddDisabledItem ( Styles . selectTileAsset ) ;
pm . AddSeparator ( "" ) ;
if ( clipboardView . unlocked )
pm . AddItem ( Styles . lockPaletteEditing , false , FlipLocked ) ;
else
pm . AddItem ( Styles . unlockPaletteEditing , false , FlipLocked ) ;
2022-01-12 10:39:15 +03:00
pm . AddItem ( Styles . openTilePalettePreferences , false , OpenTilePalettePreferences ) ;
2022-01-12 10:06:03 +03:00
pm . ShowAsContext ( ) ;
}
2022-01-12 10:39:15 +03:00
private void OpenTilePalettePreferences ( )
{
var settingsWindow = SettingsWindow . Show ( SettingsScope . User ) ;
settingsWindow . FilterProviders ( TilePaletteProperties . tilePalettePreferencesLookup ) ;
}
2022-01-12 10:06:03 +03:00
private void FlipLocked ( )
{
clipboardView . unlocked = ! clipboardView . unlocked ;
}
private void SelectPaintTarget ( )
{
Selection . activeObject = GridPaintingState . scenePaintTarget ;
}
private void SelectPaletteAsset ( )
{
Selection . activeObject = palette ;
}
private void SelectTileAsset ( )
{
Selection . activeObject = clipboardView . activeTile ;
}
private bool NotOverridingColor ( GridBrush defaultGridBrush )
{
foreach ( var cell in defaultGridBrush . cells )
{
TileBase tile = cell . tile ;
if ( tile is Tile & & ( ( tile as Tile ) . flags & TileFlags . LockColor ) = = 0 )
{
return true ;
}
}
return false ;
}
private void DoBrushesDropdownToolbar ( )
{
GUIContent content = GUIContent . Temp ( GridPaintingState . gridBrush . name ) ;
2022-01-12 10:39:15 +03:00
if ( EditorGUILayout . DropdownButton ( content , FocusType . Passive , EditorStyles . toolbarPopup , Styles . dropdownOptions ) )
2022-01-12 10:06:03 +03:00
{
var menuData = new GridBrushesDropdown . MenuItemProvider ( ) ;
var flexibleMenu = new GridBrushesDropdown ( menuData , GridPaletteBrushes . brushes . IndexOf ( GridPaintingState . gridBrush ) , null , SelectBrush , k_DropdownWidth ) ;
PopupWindow . Show ( GUILayoutUtility . topLevel . GetLast ( ) , flexibleMenu ) ;
}
if ( Event . current . type = = EventType . Repaint )
{
var dragRect = GUILayoutUtility . GetLastRect ( ) ;
var dragIconRect = new Rect ( ) ;
dragIconRect . x = dragRect . x + dragRect . width + Styles . dragPadding ;
dragIconRect . y = dragRect . y + ( dragRect . height - Styles . dragHandle . fixedHeight ) / 2 + 1 ;
dragIconRect . width = position . width - ( dragIconRect . x ) - Styles . dragPadding ;
dragIconRect . height = Styles . dragHandle . fixedHeight ;
Styles . dragHandle . Draw ( dragIconRect , GUIContent . none , false , false , false , false ) ;
}
GUILayout . FlexibleSpace ( ) ;
}
private void SelectBrush ( int i , object o )
{
GridPaintingState . gridBrush = GridPaletteBrushes . brushes [ i ] ;
}
public void OnEnable ( )
{
2022-01-12 10:39:15 +03:00
m_Enabled = true ;
2022-01-12 10:06:03 +03:00
instances . Add ( this ) ;
if ( clipboardView = = null )
{
clipboardView = CreateInstance < GridPaintPaletteClipboard > ( ) ;
clipboardView . owner = this ;
clipboardView . hideFlags = HideFlags . HideAndDontSave ;
clipboardView . unlocked = false ;
}
if ( m_PaintableSceneViewGrid = = null )
{
m_PaintableSceneViewGrid = CreateInstance < PaintableSceneViewGrid > ( ) ;
m_PaintableSceneViewGrid . hideFlags = HideFlags . HideAndDontSave ;
}
GridPaletteBrushes . FlushCache ( ) ;
ShortcutIntegration . instance . profileManager . shortcutBindingChanged + = UpdateTooltips ;
GridSelection . gridSelectionChanged + = OnGridSelectionChanged ;
GridPaintingState . RegisterPainterInterest ( this ) ;
GridPaintingState . scenePaintTargetChanged + = OnScenePaintTargetChanged ;
GridPaintingState . brushChanged + = OnBrushChanged ;
SceneView . duringSceneGui + = OnSceneViewGUI ;
PrefabUtility . prefabInstanceUpdated + = PrefabInstanceUpdated ;
EditorApplication . projectWasLoaded + = OnProjectLoaded ;
AssetPreview . SetPreviewTextureCacheSize ( 256 , GetInstanceID ( ) ) ;
wantsMouseMove = true ;
wantsMouseEnterLeaveWindow = true ;
if ( m_PreviewResizer = = null )
{
m_PreviewResizer = new PreviewResizer ( ) ;
m_PreviewResizer . Init ( "TilemapBrushInspector" ) ;
}
minSize = k_MinWindowSize ;
if ( palette = = null & & ! String . IsNullOrEmpty ( lastTilemapPalette ) )
{
palette = GridPalettes . palettes
. Where ( ( palette , index ) = > ( AssetDatabase . GetAssetPath ( palette ) = = lastTilemapPalette ) )
. FirstOrDefault ( ) ;
}
if ( palette = = null & & GridPalettes . palettes . Count > 0 )
{
palette = GridPalettes . palettes [ 0 ] ;
}
2022-01-12 10:39:15 +03:00
ToolManager . activeToolChanged + = ActiveToolChanged ;
ToolManager . activeToolChanging + = ActiveToolChanging ;
2022-01-12 10:06:03 +03:00
ShortcutIntegration . instance . contextManager . RegisterToolContext ( m_ShortcutContext ) ;
}
private static void UpdateTooltips ( IShortcutProfileManager obj , Identifier identifier , ShortcutBinding oldBinding , ShortcutBinding newBinding )
{
TilemapEditorTool . UpdateTooltips ( ) ;
}
private void PrefabInstanceUpdated ( GameObject updatedPrefab )
{
// case 947462: Reset the palette instance after its prefab has been updated as it could have been changed
if ( m_PaletteInstance ! = null & & PrefabUtility . GetCorrespondingObjectFromSource ( updatedPrefab ) = = m_Palette & & ! GridPaintingState . savingPalette )
{
ResetPreviewInstance ( ) ;
Repaint ( ) ;
}
}
private void OnProjectLoaded ( )
{
// ShortcutIntegration instance is recreated after LoadLayout which wipes the OnEnable registration
ShortcutIntegration . instance . contextManager . RegisterToolContext ( m_ShortcutContext ) ;
}
private void OnBrushChanged ( GridBrushBase brush )
{
DisableFocus ( ) ;
if ( brush is GridBrush )
EnableFocus ( ) ;
SceneView . RepaintAll ( ) ;
}
private void OnGridSelectionChanged ( )
{
Repaint ( ) ;
}
public void OnDisable ( )
{
2022-01-12 10:39:15 +03:00
m_Enabled = false ;
2022-01-12 10:06:03 +03:00
DisableFocus ( ) ;
focusMode = TilemapFocusMode . None ;
CallOnToolDeactivated ( ) ;
instances . Remove ( this ) ;
if ( instances . Count < = 1 )
GridPaintingState . gridBrush = null ;
DestroyPreviewInstance ( ) ;
DestroyImmediate ( clipboardView ) ;
DestroyImmediate ( m_PaintableSceneViewGrid ) ;
if ( m_PreviewUtility ! = null )
m_PreviewUtility . Cleanup ( ) ;
m_PreviewUtility = null ;
if ( PaintableGrid . InGridEditMode ( ) )
{
// Set Editor Tool to an always available Tool, as Tile Palette Tools are not available any more
2022-01-12 10:39:15 +03:00
ToolManager . SetActiveTool < UnityEditor . RectTool > ( ) ;
2022-01-12 10:06:03 +03:00
}
ShortcutIntegration . instance . profileManager . shortcutBindingChanged - = UpdateTooltips ;
2022-01-12 10:39:15 +03:00
ToolManager . activeToolChanged - = ActiveToolChanged ;
ToolManager . activeToolChanging - = ActiveToolChanging ;
2022-01-12 10:06:03 +03:00
GridSelection . gridSelectionChanged - = OnGridSelectionChanged ;
SceneView . duringSceneGui - = OnSceneViewGUI ;
GridPaintingState . scenePaintTargetChanged - = OnScenePaintTargetChanged ;
GridPaintingState . brushChanged - = OnBrushChanged ;
GridPaintingState . UnregisterPainterInterest ( this ) ;
PrefabUtility . prefabInstanceUpdated - = PrefabInstanceUpdated ;
EditorApplication . projectWasLoaded - = OnProjectLoaded ;
ShortcutIntegration . instance . contextManager . DeregisterToolContext ( m_ShortcutContext ) ;
}
private void OnScenePaintTargetChanged ( GameObject scenePaintTarget )
{
DisableFocus ( ) ;
EnableFocus ( ) ;
Repaint ( ) ;
}
private void ActiveToolChanged ( )
{
if ( GridPaintingState . gridBrush ! = null & & PaintableGrid . InGridEditMode ( ) & & GridPaintingState . activeBrushEditor ! = null )
{
2022-01-12 10:39:15 +03:00
GridBrushBase . Tool tool = PaintableGrid . EditTypeToBrushTool ( ToolManager . activeToolType ) ;
2022-01-12 10:06:03 +03:00
GridPaintingState . activeBrushEditor . OnToolActivated ( tool ) ;
m_PreviousToolActivatedEditor = GridPaintingState . activeBrushEditor ;
m_PreviousToolActivated = tool ;
for ( int i = 0 ; i < k_SceneViewEditModes . Length ; + + i )
{
if ( k_SceneViewEditModes [ i ] = = tool )
{
Cursor . SetCursor ( MouseStyles . mouseCursorTextures [ i ] ,
MouseStyles . mouseCursorTextures [ i ] ! = null ? MouseStyles . mouseCursorOSHotspot [ ( int ) SystemInfo . operatingSystemFamily ] : Vector2 . zero ,
CursorMode . Auto ) ;
break ;
}
}
}
else
{
Cursor . SetCursor ( null , Vector2 . zero , CursorMode . Auto ) ;
}
Repaint ( ) ;
}
private void ActiveToolChanging ( )
{
if ( ! TilemapEditorTool . IsActive ( typeof ( MoveTool ) ) & & ! TilemapEditorTool . IsActive ( typeof ( SelectTool ) ) )
{
GridSelection . Clear ( ) ;
}
CallOnToolDeactivated ( ) ;
}
private void CallOnToolDeactivated ( )
{
if ( GridPaintingState . gridBrush ! = null & & m_PreviousToolActivatedEditor ! = null )
{
m_PreviousToolActivatedEditor . OnToolDeactivated ( m_PreviousToolActivated ) ;
m_PreviousToolActivatedEditor = null ;
if ( ! PaintableGrid . InGridEditMode ( ) )
Cursor . SetCursor ( null , Vector2 . zero , CursorMode . Auto ) ;
}
}
internal void ResetZPosition ( )
{
GridPaintingState . gridBrush . ResetZPosition ( ) ;
GridPaintingState . lastActiveGrid . ResetZPosition ( ) ;
}
private void OnBrushInspectorGUI ( )
{
if ( GridPaintingState . gridBrush = = null )
return ;
// Brush Inspector GUI
EditorGUI . BeginChangeCheck ( ) ;
if ( GridPaintingState . activeBrushEditor ! = null )
GridPaintingState . activeBrushEditor . OnPaintInspectorGUI ( ) ;
else if ( GridPaintingState . fallbackEditor ! = null )
GridPaintingState . fallbackEditor . OnInspectorGUI ( ) ;
if ( EditorGUI . EndChangeCheck ( ) )
{
GridPaletteBrushes . ActiveGridBrushAssetChanged ( ) ;
}
// Z Position Inspector
var hasLastActiveGrid = GridPaintingState . lastActiveGrid ! = null ;
using ( new EditorGUI . DisabledScope ( ! hasLastActiveGrid ) )
{
2022-01-12 10:39:15 +03:00
var lockZPosition = false ;
2022-01-12 10:06:03 +03:00
if ( GridPaintingState . activeBrushEditor ! = null )
{
EditorGUI . BeginChangeCheck ( ) ;
2022-01-12 10:39:15 +03:00
lockZPosition = EditorGUILayout . Toggle ( Styles . lockZPosition , ! GridPaintingState . activeBrushEditor . canChangeZPosition ) ;
2022-01-12 10:06:03 +03:00
if ( EditorGUI . EndChangeCheck ( ) )
2022-01-12 10:39:15 +03:00
GridPaintingState . activeBrushEditor . canChangeZPosition = ! lockZPosition ;
2022-01-12 10:06:03 +03:00
}
2022-01-12 10:39:15 +03:00
using ( new EditorGUI . DisabledScope ( lockZPosition ) )
2022-01-12 10:06:03 +03:00
{
EditorGUILayout . BeginHorizontal ( ) ;
EditorGUI . BeginChangeCheck ( ) ;
var zPosition = EditorGUILayout . DelayedIntField ( Styles . zPosition , hasLastActiveGrid ? GridPaintingState . lastActiveGrid . zPosition : 0 ) ;
if ( EditorGUI . EndChangeCheck ( ) )
{
GridPaintingState . gridBrush . ChangeZPosition ( zPosition - GridPaintingState . lastActiveGrid . zPosition ) ;
GridPaintingState . lastActiveGrid . zPosition = zPosition ;
}
if ( GUILayout . Button ( Styles . resetZPosition ) )
{
ResetZPosition ( ) ;
}
EditorGUILayout . EndHorizontal ( ) ;
}
}
}
private bool IsObjectPrefabInstance ( Object target )
{
return target ! = null & & PrefabUtility . IsPartOfRegularPrefab ( target ) ;
}
private GameObject FindPrefabInstanceEquivalent ( GameObject prefabInstance , GameObject prefabTarget )
{
var prefabRoot = prefabTarget . transform . root . gameObject ;
var currentTransform = prefabTarget . transform ;
var reverseTransformOrder = new Stack < int > ( ) ;
while ( currentTransform ! = prefabRoot . transform & & currentTransform . parent ! = null )
{
var parentTransform = currentTransform . parent ;
for ( int i = 0 ; i < parentTransform . childCount ; + + i )
{
if ( currentTransform = = parentTransform . GetChild ( i ) )
{
reverseTransformOrder . Push ( i ) ;
break ;
}
}
currentTransform = currentTransform . parent ;
}
currentTransform = prefabInstance . transform ;
while ( reverseTransformOrder . Count > 0 )
{
var childIndex = reverseTransformOrder . Pop ( ) ;
if ( childIndex > = currentTransform . childCount )
return null ;
currentTransform = currentTransform . GetChild ( childIndex ) ;
}
return currentTransform . gameObject ;
}
private void GoToPrefabMode ( GameObject target )
{
var prefabObject = PrefabUtility . GetCorrespondingObjectFromSource ( target ) ;
var assetPath = AssetDatabase . GetAssetPath ( prefabObject ) ;
var stage = PrefabStageUtility . OpenPrefab ( assetPath ) ;
var prefabInstance = stage . prefabContentsRoot ;
var prefabTarget = FindPrefabInstanceEquivalent ( prefabInstance , prefabObject ) ;
if ( prefabTarget ! = null )
{
GridPaintingState . scenePaintTarget = prefabTarget ;
}
}
private void DoActiveTargetsGUI ( )
{
using ( new EditorGUI . DisabledScope ( GridPaintingState . validTargets = = null | | GridPaintingState . scenePaintTarget = = null ) )
{
bool hasPaintTarget = GridPaintingState . scenePaintTarget ! = null ;
bool needWarning = IsObjectPrefabInstance ( GridPaintingState . scenePaintTarget ) ;
GUILayout . Label ( Styles . activeTargetLabel , GUILayout . Width ( k_ActiveTargetLabelWidth ) , GUILayout . Height ( k_ActiveTargetWarningSize ) ) ;
GUIContent content = GUIContent . Temp ( hasPaintTarget ? GridPaintingState . scenePaintTarget . name : "Nothing" ) ;
if ( EditorGUILayout . DropdownButton ( content , FocusType . Passive , EditorStyles . popup , GUILayout . Width ( k_ActiveTargetDropdownWidth - ( needWarning ? k_ActiveTargetWarningSize : 0f ) ) , GUILayout . Height ( k_ActiveTargetWarningSize ) ) )
{
int index = hasPaintTarget ? Array . IndexOf ( GridPaintingState . validTargets , GridPaintingState . scenePaintTarget ) : 0 ;
var menuData = new GridPaintTargetsDropdown . MenuItemProvider ( ) ;
var flexibleMenu = new GridPaintTargetsDropdown ( menuData , index , null , SelectTarget , k_ActiveTargetDropdownWidth ) ;
PopupWindow . Show ( GUILayoutUtility . topLevel . GetLast ( ) , flexibleMenu ) ;
}
if ( needWarning )
GUILayout . Label ( Styles . prefabWarningIcon , GUILayout . Width ( k_ActiveTargetWarningSize ) , GUILayout . Height ( k_ActiveTargetWarningSize ) ) ;
}
}
private void SelectTarget ( int i , object o )
{
var obj = o as GameObject ;
var isPrefabInstance = IsObjectPrefabInstance ( obj ) ;
if ( isPrefabInstance )
{
var editMode = ( TilePaletteProperties . PrefabEditModeSettings ) EditorPrefs . GetInt ( TilePaletteProperties . targetEditModeEditorPref , 0 ) ;
switch ( editMode )
{
case TilePaletteProperties . PrefabEditModeSettings . EnableDialog :
{
var option = EditorUtility . DisplayDialogComplex ( TilePaletteProperties . targetEditModeDialogTitle
, TilePaletteProperties . targetEditModeDialogMessage
, TilePaletteProperties . targetEditModeDialogYes
, TilePaletteProperties . targetEditModeDialogNo
, TilePaletteProperties . targetEditModeDialogChange ) ;
switch ( option )
{
case 0 :
GoToPrefabMode ( obj ) ;
return ;
case 1 :
// Do nothing here for "No"
break ;
case 2 :
var settingsWindow = SettingsWindow . Show ( SettingsScope . User ) ;
settingsWindow . FilterProviders ( TilePaletteProperties . targetEditModeLookup ) ;
break ;
}
}
break ;
case TilePaletteProperties . PrefabEditModeSettings . EditInPrefabMode :
GoToPrefabMode ( obj ) ;
return ;
case TilePaletteProperties . PrefabEditModeSettings . EditInScene :
default :
break ;
}
}
GridPaintingState . scenePaintTarget = obj ;
if ( GridPaintingState . scenePaintTarget ! = null )
EditorGUIUtility . PingObject ( GridPaintingState . scenePaintTarget ) ;
}
private void DoClipboardHeader ( )
{
if ( ! GridPalettes . palettes . Contains ( palette ) | | palette = = null ) // Palette not in list means it was deleted
{
GridPalettes . CleanCache ( ) ;
if ( GridPalettes . palettes . Count > 0 )
{
palette = GridPalettes . palettes . LastOrDefault ( ) ;
}
}
EditorGUILayout . BeginHorizontal ( ) ;
DoPalettesDropdown ( ) ;
using ( new EditorGUI . DisabledScope ( palette = = null ) )
{
clipboardView . unlocked = GUILayout . Toggle ( clipboardView . unlocked ,
clipboardView . isModified ? Styles . editModified : Styles . edit ,
EditorStyles . toolbarButton ) ;
}
GUILayout . FlexibleSpace ( ) ;
2022-01-12 10:39:15 +03:00
using ( new EditorGUI . DisabledScope ( palette = = null ) )
{
EditorGUI . BeginChangeCheck ( ) ;
m_DrawGizmos = GUILayout . Toggle ( m_DrawGizmos , Styles . gizmos , EditorStyles . toolbarButton ) ;
if ( EditorGUI . EndChangeCheck ( ) )
{
if ( m_DrawGizmos )
{
clipboardView . SavePaletteIfNecessary ( ) ;
ResetPreviewInstance ( ) ;
}
Repaint ( ) ;
}
}
2022-01-12 10:06:03 +03:00
EditorGUILayout . EndHorizontal ( ) ;
}
private void DoPalettesDropdown ( )
{
string name = palette ! = null ? palette . name : Styles . createNewPalette . text ;
2022-01-12 10:39:15 +03:00
Rect rect = GUILayoutUtility . GetRect ( GUIContent . Temp ( name ) , EditorStyles . toolbarDropDown , Styles . dropdownOptions ) ;
2022-01-12 10:06:03 +03:00
if ( GridPalettes . palettes . Count = = 0 )
{
if ( EditorGUI . DropdownButton ( rect , GUIContent . Temp ( name ) , FocusType . Passive , EditorStyles . toolbarDropDown ) )
{
OpenAddPalettePopup ( rect ) ;
}
}
else
{
GUIContent content = GUIContent . Temp ( GridPalettes . palettes . Count > 0 & & palette ! = null ? palette . name : Styles . createNewPalette . text ) ;
if ( EditorGUI . DropdownButton ( rect , content , FocusType . Passive , EditorStyles . toolbarPopup ) )
{
var menuData = new GridPalettesDropdown . MenuItemProvider ( ) ;
m_PaletteDropdown = new GridPalettesDropdown ( menuData , GridPalettes . palettes . IndexOf ( palette ) , null , SelectPalette , k_DropdownWidth ) ;
PopupWindow . Show ( GUILayoutUtility . topLevel . GetLast ( ) , m_PaletteDropdown ) ;
}
}
}
private void SelectPalette ( int i , object o )
{
if ( i < GridPalettes . palettes . Count )
{
palette = GridPalettes . palettes [ i ] ;
}
else
{
m_PaletteDropdown . editorWindow . Close ( ) ;
OpenAddPalettePopup ( new Rect ( 0 , 0 , 0 , 0 ) ) ;
}
}
private void OpenAddPalettePopup ( Rect rect )
{
bool popupOpened = GridPaletteAddPopup . ShowAtPosition ( rect , this ) ;
if ( popupOpened )
GUIUtility . ExitGUI ( ) ;
}
2022-01-12 10:39:15 +03:00
private void DisplayClipboardText ( GUIContent clipboardText , Rect position )
{
Color old = GUI . color ;
GUI . color = Color . gray ;
var infoSize = GUI . skin . label . CalcSize ( clipboardText ) ;
Rect rect = new Rect ( position . center . x - infoSize . x * . 5f , position . center . y - infoSize . y , 500 , 100 ) ;
GUI . Label ( rect , clipboardText ) ;
GUI . color = old ;
}
2022-01-12 10:06:03 +03:00
private void OnClipboardGUI ( Rect position )
{
if ( Event . current . type ! = EventType . Layout & & position . Contains ( Event . current . mousePosition ) & & GridPaintingState . activeGrid ! = clipboardView & & clipboardView . unlocked )
{
GridPaintingState . activeGrid = clipboardView ;
SceneView . RepaintAll ( ) ;
}
// Validate palette (case 1017965)
GUIContent paletteError = null ;
if ( palette = = null )
{
if ( GridPalettes . palettes . Count = = 0 )
paletteError = Styles . emptyProjectInfo ;
else
paletteError = Styles . invalidPaletteInfo ;
}
else if ( palette . GetComponent < Grid > ( ) = = null )
{
paletteError = Styles . invalidGridInfo ;
}
if ( paletteError ! = null )
{
2022-01-12 10:39:15 +03:00
DisplayClipboardText ( paletteError , position ) ;
2022-01-12 10:06:03 +03:00
return ;
}
bool oldEnabled = GUI . enabled ;
GUI . enabled = ! clipboardView . showNewEmptyClipboardInfo | | DragAndDrop . objectReferences . Length > 0 ;
if ( Event . current . type = = EventType . Repaint )
clipboardView . guiRect = position ;
2022-01-12 10:39:15 +03:00
if ( m_DelayedResetPaletteInstance )
ResetPreviewInstance ( ) ;
2022-01-12 10:06:03 +03:00
EditorGUI . BeginChangeCheck ( ) ;
clipboardView . OnGUI ( ) ;
if ( EditorGUI . EndChangeCheck ( ) )
Repaint ( ) ;
GUI . enabled = oldEnabled ;
if ( clipboardView . showNewEmptyClipboardInfo )
{
2022-01-12 10:39:15 +03:00
DisplayClipboardText ( Styles . emptyPaletteInfo , position ) ;
2022-01-12 10:06:03 +03:00
}
}
2022-01-12 10:39:15 +03:00
private void ConvertGridPrefabToPalette ( Rect targetPosition )
2022-01-12 10:06:03 +03:00
{
2022-01-12 10:39:15 +03:00
if ( ! targetPosition . Contains ( Event . current . mousePosition )
2022-01-12 10:06:03 +03:00
| | ( Event . current . type ! = EventType . DragPerform
& & Event . current . type ! = EventType . DragUpdated )
| | DragAndDrop . objectReferences . Length ! = 1 )
return ;
var draggedObject = DragAndDrop . objectReferences [ 0 ] ;
if ( ! PrefabUtility . IsPartOfRegularPrefab ( draggedObject ) )
return ;
switch ( Event . current . type )
{
case EventType . DragUpdated :
{
DragAndDrop . visualMode = DragAndDropVisualMode . Generic ;
Event . current . Use ( ) ;
GUI . changed = true ;
}
break ;
case EventType . DragPerform :
{
var path = AssetDatabase . GetAssetPath ( draggedObject ) ;
var assets = AssetDatabase . LoadAllAssetsAtPath ( path ) ;
bool hasNewPaletteAsset = false ;
Grid gridPrefab = null ;
foreach ( var asset in assets )
{
var gridPalette = asset as GridPalette ;
hasNewPaletteAsset | = gridPalette ! = null ;
GameObject go = asset as GameObject ;
if ( go ! = null )
{
var grid = go . GetComponent < Grid > ( ) ;
if ( grid ! = null )
gridPrefab = grid ;
}
}
2022-01-12 10:39:15 +03:00
if ( ! hasNewPaletteAsset & & gridPrefab ! = null )
2022-01-12 10:06:03 +03:00
{
var cellLayout = gridPrefab . cellLayout ;
var cellSizing = ( cellLayout = = GridLayout . CellLayout . Rectangle
| | cellLayout = = GridLayout . CellLayout . Hexagon )
? GridPalette . CellSizing . Automatic
: GridPalette . CellSizing . Manual ;
var newPalette = GridPaletteUtility . CreateGridPalette ( cellSizing ) ;
AssetDatabase . AddObjectToAsset ( newPalette , path ) ;
AssetDatabase . ForceReserializeAssets ( new string [ ] { path } ) ;
AssetDatabase . SaveAssets ( ) ;
Event . current . Use ( ) ;
GUIUtility . ExitGUI ( ) ;
}
}
break ;
}
}
private void OnSceneViewGUI ( SceneView sceneView )
{
if ( GridPaintingState . defaultBrush ! = null & & GridPaintingState . scenePaintTarget ! = null )
SceneViewOverlay . Window ( Styles . rendererOverlayTitleLabel , DisplayFocusMode , ( int ) SceneViewOverlay . Ordering . TilemapRenderer , SceneViewOverlay . WindowDisplayOption . OneWindowPerTitle ) ;
else if ( focusMode ! = TilemapFocusMode . None )
{
// case 946284: Disable Focus if focus mode is set but there is nothing to focus on
DisableFocus ( ) ;
focusMode = TilemapFocusMode . None ;
}
}
2022-01-12 10:39:15 +03:00
internal void SetFocusMode ( TilemapFocusMode tilemapFocusMode )
{
if ( tilemapFocusMode ! = focusMode )
{
DisableFocus ( ) ;
focusMode = tilemapFocusMode ;
EnableFocus ( ) ;
}
}
2022-01-12 10:06:03 +03:00
private void DisplayFocusMode ( Object displayTarget , SceneView sceneView )
{
var labelWidth = EditorGUIUtility . labelWidth ;
var fieldWidth = EditorGUIUtility . fieldWidth ;
EditorGUIUtility . labelWidth = EditorGUIUtility . fieldWidth =
0.5f * ( EditorGUIUtility . labelWidth + EditorGUIUtility . fieldWidth ) ;
2022-01-12 10:39:15 +03:00
var newFocus = ( TilemapFocusMode ) EditorGUILayout . EnumPopup ( Styles . focusLabel , focusMode ) ;
SetFocusMode ( newFocus ) ;
2022-01-12 10:06:03 +03:00
EditorGUIUtility . labelWidth = labelWidth ;
EditorGUIUtility . fieldWidth = fieldWidth ;
}
2022-01-12 10:39:15 +03:00
private void FilterSingleSceneObjectInScene ( int instanceID )
{
if ( SceneView . lastActiveSceneView ! = null )
SceneView . lastActiveSceneView . SetSceneViewFiltering ( true ) ;
StageHandle currentStageHandle = StageUtility . GetCurrentStageHandle ( ) ;
if ( currentStageHandle . IsValid ( ) & & ! currentStageHandle . isMainStage )
{
HierarchyProperty . FilterSingleSceneObjectInScene ( instanceID
, false
, new UnityEngine . SceneManagement . Scene [ ] { currentStageHandle . customScene } ) ;
}
else
{
HierarchyProperty . FilterSingleSceneObject ( instanceID , false ) ;
}
if ( SceneView . lastActiveSceneView ! = null )
SceneView . lastActiveSceneView . Repaint ( ) ;
}
2022-01-12 10:06:03 +03:00
private void EnableFocus ( )
{
if ( GridPaintingState . scenePaintTarget = = null )
return ;
switch ( focusMode )
{
case TilemapFocusMode . Tilemap :
{
2022-01-12 10:39:15 +03:00
FilterSingleSceneObjectInScene ( GridPaintingState . scenePaintTarget . GetInstanceID ( ) ) ;
2022-01-12 10:06:03 +03:00
break ;
}
case TilemapFocusMode . Grid :
{
Tilemap tilemap = GridPaintingState . scenePaintTarget . GetComponent < Tilemap > ( ) ;
if ( tilemap ! = null & & tilemap . layoutGrid ! = null )
{
2022-01-12 10:39:15 +03:00
FilterSingleSceneObjectInScene ( tilemap . layoutGrid . gameObject . GetInstanceID ( ) ) ;
2022-01-12 10:06:03 +03:00
}
break ;
}
default :
{
break ;
}
}
}
private void DisableFocus ( )
{
if ( focusMode = = TilemapFocusMode . None )
return ;
2022-01-12 10:39:15 +03:00
StageHandle currentStageHandle = StageUtility . GetCurrentStageHandle ( ) ;
if ( currentStageHandle . IsValid ( ) & & ! currentStageHandle . isMainStage )
{
HierarchyProperty . ClearSceneObjectsFilterInScene ( new UnityEngine . SceneManagement . Scene [ ] { currentStageHandle . customScene } ) ;
}
else
{
HierarchyProperty . ClearSceneObjectsFilter ( ) ;
}
2022-01-12 10:06:03 +03:00
if ( SceneView . lastActiveSceneView ! = null )
2022-01-12 10:39:15 +03:00
{
2022-01-12 10:06:03 +03:00
SceneView . lastActiveSceneView . SetSceneViewFiltering ( false ) ;
2022-01-12 10:39:15 +03:00
SceneView . lastActiveSceneView . Repaint ( ) ;
}
2022-01-12 10:06:03 +03:00
}
[MenuItem("Window/2D/Tile Palette", false, 2)]
public static void OpenTilemapPalette ( )
{
GridPaintPaletteWindow w = GetWindow < GridPaintPaletteWindow > ( ) ;
w . titleContent = Styles . tilePalette ;
}
// TODO: Better way of clearing caches than AssetPostprocessor
public class AssetProcessor : AssetPostprocessor
{
public override int GetPostprocessOrder ( )
{
return int . MaxValue ;
}
private static void OnPostprocessAllAssets ( string [ ] importedAssets , string [ ] deletedAssets , string [ ] movedAssets , string [ ] movedFromPath )
{
if ( GridPaintingState . savingPalette )
return ;
foreach ( var window in instances )
{
2022-01-12 10:39:15 +03:00
window . DelayedResetPreviewInstance ( ) ;
2022-01-12 10:06:03 +03:00
}
}
}
public class PaletteAssetModificationProcessor : AssetModificationProcessor
{
static void OnWillCreateAsset ( string assetName )
{
2022-01-12 10:39:15 +03:00
SavePalettesIfRequired ( null ) ;
2022-01-12 10:06:03 +03:00
}
static string [ ] OnWillSaveAssets ( string [ ] paths )
{
2022-01-12 10:39:15 +03:00
SavePalettesIfRequired ( paths ) ;
2022-01-12 10:06:03 +03:00
return paths ;
}
2022-01-12 10:39:15 +03:00
static void SavePalettesIfRequired ( string [ ] paths )
2022-01-12 10:06:03 +03:00
{
if ( GridPaintingState . savingPalette )
return ;
foreach ( var window in instances )
{
if ( window . clipboardView . isModified )
{
2022-01-12 10:39:15 +03:00
window . clipboardView . CheckRevertIfChanged ( paths ) ;
2022-01-12 10:06:03 +03:00
window . clipboardView . SavePaletteIfNecessary ( ) ;
window . Repaint ( ) ;
}
}
}
}
}
}