123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- using System;
- using UnityEngine;
- using UnityEngine.Tilemaps;
- using UnityEngine.UIElements;
-
- namespace UnityEditor.Tilemaps
- {
- internal class PaintableSceneViewGrid : PaintableGrid
- {
- private Transform gridTransform { get { return grid != null ? grid.transform : null; } }
- private Grid grid { get { return brushTarget != null ? brushTarget.GetComponentInParent<Grid>() : (Selection.activeGameObject != null ? Selection.activeGameObject.GetComponentInParent<Grid>() : null); } }
- private GridBrushBase gridBrush { get { return GridPaintingState.gridBrush; } }
- private SceneView activeSceneView;
- private int sceneViewTransformHash;
-
- private GameObject brushTarget
- {
- get { return GridPaintingState.scenePaintTarget; }
- }
-
- public Tilemap tilemap
- {
- get
- {
- if (brushTarget != null)
- {
- return brushTarget.GetComponent<Tilemap>();
- }
- return null;
- }
- }
-
- public Action<GameObject> onEdited;
-
- protected override void OnEnable()
- {
- base.OnEnable();
- SceneView.duringSceneGui += OnSceneGUI;
- Undo.undoRedoPerformed += UndoRedoPerformed;
- GridSelection.gridSelectionChanged += OnGridSelectionChanged;
- }
-
- protected override void OnDisable()
- {
- SceneView.duringSceneGui -= OnSceneGUI;
- Undo.undoRedoPerformed -= UndoRedoPerformed;
- GridSelection.gridSelectionChanged -= OnGridSelectionChanged;
- base.OnDisable();
- }
-
- private void OnGridSelectionChanged()
- {
- SceneView.RepaintAll();
- }
-
- private Rect GetSceneViewPositionRect(SceneView sceneView)
- {
- return new Rect(0, 0, sceneView.position.width, sceneView.position.height);
- }
-
- public void OnSceneGUI(SceneView sceneView)
- {
- HandleMouseEnterLeave(sceneView);
-
- CallOnSceneGUI();
-
- // Case 1093801: Handle only the currently active scene view
- if (sceneView != activeSceneView)
- return;
-
- // Case 1077400: SceneView camera transform changes may update the mouse grid position even though the mouse position has not changed
- var currentSceneViewTransformHash = sceneView.camera.transform.localToWorldMatrix.GetHashCode();
- UpdateMouseGridPosition(currentSceneViewTransformHash != sceneViewTransformHash);
- sceneViewTransformHash = currentSceneViewTransformHash;
-
- var dot = 1.0f;
- var gridView = GetGridView();
- if (gridView != null)
- {
- dot = Math.Abs(Vector3.Dot(sceneView.camera.transform.forward, Grid.Swizzle(gridView.cellSwizzle, gridView.transform.forward)));
- }
-
- // Case 1021655: Validate that grid is not totally parallel to view (+-5 degrees), otherwise tiles could be accidentally painted on large positions
- if (dot > 0.1f)
- {
- base.OnGUI();
- if (InGridEditMode())
- {
- if ((grid != null) && (GridPaintingState.activeGrid == this || GridSelection.active))
- {
- CallOnPaintSceneGUI();
- }
- if (Event.current.type == EventType.Repaint)
- EditorGUIUtility.AddCursorRect(GetSceneViewPositionRect(sceneView), MouseCursor.CustomCursor);
- }
- }
- }
-
- private void HandleMouseEnterLeave(SceneView sceneView)
- {
- if (GridPaintingState.isEditing)
- {
- if (Event.current.type == EventType.MouseEnterWindow)
- {
- OnMouseEnter(sceneView);
- }
- else if (Event.current.type == EventType.MouseLeaveWindow)
- {
- OnMouseLeave();
- }
- // Case 1043365: When docked, the docking area is considered part of the window and MouseEnter/LeaveWindow events are not considered when entering the docking area
- else if (sceneView.docked)
- {
- var guiPoint = Event.current.mousePosition;
- var sceneViewPosition = GetSceneViewPositionRect(sceneView);
- if (sceneViewPosition.Contains(guiPoint))
- {
- if (GridPaintingState.activeGrid != this)
- {
- OnMouseEnter(sceneView);
- }
- }
- else if (activeSceneView == sceneView)
- {
- if (GridPaintingState.activeGrid == this)
- {
- OnMouseLeave();
- }
- }
- }
- }
- }
-
- private void OnMouseEnter(SceneView sceneView)
- {
- if (GridPaintingState.activeBrushEditor != null)
- GridPaintingState.activeBrushEditor.OnMouseEnter();
- activeSceneView = sceneView;
- GridPaintingState.AddActiveGrid(this);
- UpdateMouseGridPosition(true);
- ResetPreviousMousePositionToCurrentPosition();
- }
-
- private void OnMouseLeave()
- {
- if (GridPaintingState.activeBrushEditor != null)
- GridPaintingState.activeBrushEditor.OnMouseLeave();
- GridPaintingState.RemoveActiveGrid(this);
- activeSceneView = null;
- }
-
- private void UndoRedoPerformed()
- {
- RefreshAllTiles();
- }
-
- private void RefreshAllTiles()
- {
- if (tilemap != null)
- tilemap.RefreshAllTiles();
- }
-
- protected override void RegisterUndo()
- {
- if (GridPaintingState.activeBrushEditor != null)
- {
- GridPaintingState.activeBrushEditor.RegisterUndo(brushTarget, EditTypeToBrushTool(EditorTools.ToolManager.activeToolType));
- }
- }
-
- protected override void Paint(Vector3Int position)
- {
- if (grid != null)
- gridBrush.Paint(grid, brushTarget, position);
- }
-
- protected override void Erase(Vector3Int position)
- {
- if (grid != null)
- gridBrush.Erase(grid, brushTarget, position);
- }
-
- protected override void BoxFill(BoundsInt position)
- {
- if (grid != null)
- gridBrush.BoxFill(grid, brushTarget, position);
- }
-
- protected override void BoxErase(BoundsInt position)
- {
- if (grid != null)
- gridBrush.BoxErase(grid, brushTarget, position);
- }
-
- protected override void FloodFill(Vector3Int position)
- {
- if (grid != null)
- gridBrush.FloodFill(grid, brushTarget, position);
- }
-
- protected override void PickBrush(BoundsInt position, Vector3Int pickStart)
- {
- if (grid != null)
- gridBrush.Pick(grid, brushTarget, position, pickStart);
- }
-
- protected override void Select(BoundsInt position)
- {
- if (grid != null)
- {
- GridSelection.Select(brushTarget, position);
- gridBrush.Select(grid, brushTarget, position);
- }
- }
-
- protected override void Move(BoundsInt from, BoundsInt to)
- {
- if (grid != null)
- gridBrush.Move(grid, brushTarget, from, to);
- }
-
- protected override void MoveStart(BoundsInt position)
- {
- if (grid != null)
- gridBrush.MoveStart(grid, brushTarget, position);
- }
-
- protected override void MoveEnd(BoundsInt position)
- {
- if (grid != null)
- gridBrush.MoveEnd(grid, brushTarget, position);
- }
-
- protected override bool CustomTool(bool isToolHotControl, TilemapEditorTool tool, Vector3Int position)
- {
- var executed = false;
- if (grid != null)
- {
- executed = tool.HandleTool(isToolHotControl, grid, brushTarget, position);
- }
- return executed;
- }
-
- protected override void OnEditStart()
- {
- if (GridPaintingState.activeBrushEditor != null && grid != null)
- GridPaintingState.activeBrushEditor.OnEditStart(grid, brushTarget);
- onEdited?.Invoke(brushTarget);
- }
-
- protected override void OnEditEnd()
- {
- if (GridPaintingState.activeBrushEditor != null && grid != null)
- GridPaintingState.activeBrushEditor.OnEditEnd(grid, brushTarget);
- }
-
- protected override void ClearGridSelection()
- {
- GridSelection.Clear();
- }
-
- public override bool isActive => grid != null;
-
- public override Rect rectPosition => activeSceneView != null ? activeSceneView.rootVisualElement.worldBound : Rect.zero;
-
- public override VisualElement windowRoot => activeSceneView != null ? activeSceneView.rootVisualElement.GetRoot() : null;
-
- public override void Repaint()
- {
- SceneView.RepaintAll();
- }
-
- protected override bool ValidateFloodFillPosition(Vector3Int position)
- {
- return true;
- }
-
- protected override Vector2Int ScreenToGrid(Vector2 screenPosition, float zPosition)
- {
- if (tilemap != null)
- {
- var transform = tilemap.transform;
- var plane = new Plane(GetGridForward(tilemap), transform.position);
- var screenLocal = GridEditorUtility.ScreenToLocal(transform, screenPosition, plane);
- if (GridPaintingState.gridBrushMousePositionAtZ)
- screenLocal.z = zPosition;
- var cell = LocalToGrid(tilemap, screenLocal);
- return new Vector2Int(cell.x, cell.y);
- }
- if (grid != null)
- {
- var screenLocal = GridEditorUtility.ScreenToLocal(gridTransform, screenPosition, GetGridPlane(grid));
- if (GridPaintingState.gridBrushMousePositionAtZ)
- screenLocal.z = zPosition;
- var cell = LocalToGrid(grid, screenLocal);
- return new Vector2Int(cell.x, cell.y);
- }
- return Vector2Int.zero;
- }
-
- protected override bool PickingIsDefaultTool()
- {
- return false;
- }
-
- protected override bool CanPickOutsideEditMode()
- {
- return false;
- }
-
- protected override GridLayout.CellLayout CellLayout()
- {
- return grid.cellLayout;
- }
-
- Vector3Int LocalToGrid(GridLayout gridLayout, Vector3 local)
- {
- return gridLayout.LocalToCell(local);
- }
-
- private Vector3 GetGridForward(GridLayout gridLayout)
- {
- switch (gridLayout.cellSwizzle)
- {
- case GridLayout.CellSwizzle.XYZ:
- return gridLayout.transform.forward * -1f;
- case GridLayout.CellSwizzle.XZY:
- return gridLayout.transform.up * -1f;
- case GridLayout.CellSwizzle.YXZ:
- return gridLayout.transform.forward;
- case GridLayout.CellSwizzle.YZX:
- return gridLayout.transform.up;
- case GridLayout.CellSwizzle.ZXY:
- return gridLayout.transform.right;
- case GridLayout.CellSwizzle.ZYX:
- return gridLayout.transform.right * -1f;
- }
- return gridLayout.transform.forward * -1f;
- }
-
- private Plane GetGridPlane(Grid planeForGrid)
- {
- return new Plane(GetGridForward(planeForGrid), planeForGrid.transform.position);
- }
-
- private GridLayout GetGridView()
- {
- if (tilemap != null)
- return tilemap;
- if (grid != null)
- return grid;
- return null;
- }
-
- void CallOnPaintSceneGUI()
- {
- bool hasSelection = GridSelection.active && GridSelection.target == brushTarget;
- if (!hasSelection && GridPaintingState.activeGrid != this)
- return;
-
- RectInt rect = new RectInt(mouseGridPosition, new Vector2Int(1, 1));
-
- if (m_MarqueeStart.HasValue)
- rect = GridEditorUtility.GetMarqueeRect(mouseGridPosition, m_MarqueeStart.Value);
- else if (hasSelection)
- rect = new RectInt(GridSelection.position.xMin, GridSelection.position.yMin, GridSelection.position.size.x, GridSelection.position.size.y);
-
- var layoutGrid = tilemap != null ? tilemap.layoutGrid : grid as GridLayout;
- BoundsInt brushBounds = new BoundsInt(new Vector3Int(rect.x, rect.y, zPosition), new Vector3Int(rect.width, rect.height, 1));
- if (GridPaintingState.activeBrushEditor != null)
- {
- GridPaintingState.activeBrushEditor.OnPaintSceneGUI(layoutGrid, brushTarget, brushBounds
- , EditTypeToBrushTool(EditorTools.ToolManager.activeToolType), m_MarqueeStart.HasValue || executing);
- }
- else // Fallback when user hasn't defined custom editor
- {
- GridBrushEditorBase.OnPaintSceneGUIInternal(layoutGrid, brushTarget, brushBounds
- , EditTypeToBrushTool(EditorTools.ToolManager.activeToolType), m_MarqueeStart.HasValue || executing);
- }
- }
-
- void CallOnSceneGUI()
- {
- var gridLayout = tilemap != null ? tilemap : grid as GridLayout;
- bool hasSelection = GridSelection.active && GridSelection.target == brushTarget;
- if (GridPaintingState.activeBrushEditor != null)
- {
- GridPaintingState.activeBrushEditor.OnSceneGUI(gridLayout, brushTarget);
- if (hasSelection)
- {
- GridPaintingState.activeBrushEditor.OnSelectionSceneGUI(gridLayout, brushTarget);
- }
- }
-
- if (hasSelection)
- {
- RectInt rect = new RectInt(GridSelection.position.xMin, GridSelection.position.yMin, GridSelection.position.size.x, GridSelection.position.size.y);
- BoundsInt brushBounds = new BoundsInt(new Vector3Int(rect.x, rect.y, zPosition), new Vector3Int(rect.width, rect.height, 1));
- GridBrushEditorBase.OnSceneGUIInternal(gridLayout, brushTarget, brushBounds
- , EditTypeToBrushTool(EditorTools.ToolManager.activeToolType), m_MarqueeStart.HasValue || executing);
- }
- }
- }
- }
|