A game about forced loneliness, made by TACStudios
at master 147 lines 6.5 kB view raw
1using System; 2using System.Linq; 3using UnityEditor.EditorTools; 4using UnityEngine; 5using UnityEngine.Tilemaps; 6using Object = UnityEngine.Object; 7 8namespace UnityEditor.Tilemaps 9{ 10 /// <summary> 11 /// Abstract class for Editor Tool used to handle a GridSelection. 12 /// </summary> 13 public abstract class GridSelectionTool : EditorTool 14 { 15 private TileBase[] m_SelectionTiles; 16 private Color[] m_SelectionColors; 17 private Matrix4x4[] m_SelectionMatrices; 18 private TileFlags[] m_SelectionFlagsArray; 19 private Sprite[] m_SelectionSprites; 20 private Tile.ColliderType[] m_SelectionColliderTypes; 21 private int m_FirstCellWithTile; 22 23 private int selectionCellCount => Math.Abs(GridSelection.position.size.x * GridSelection.position.size.y * GridSelection.position.size.z); 24 25 /// <summary> 26 /// Does the GUI for the GridSelectionTool for an EditorWindow. 27 /// </summary> 28 /// <param name="window">EditorWindow which GUI is being done.</param> 29 public override void OnToolGUI(EditorWindow window) 30 { 31 var selection = Selection.activeObject as GridSelection; 32 if (selection == null) 33 return; 34 35 if (window is SceneView && GridSelection.target != null && GridPaintingState.IsPartOfActivePalette(GridSelection.target)) 36 return; 37 38 OnToolGUI(); 39 } 40 41 internal void OnToolGUI() 42 { 43 if (GridSelection.target == null) 44 return; 45 46 var brushTarget = GridSelection.target; 47 var tilemap = brushTarget.GetComponent<Tilemap>(); 48 if (tilemap == null) 49 return; 50 51 UpdateSelection(tilemap); 52 if (m_SelectionFlagsArray == null || m_SelectionFlagsArray.Length <= 0) 53 return; 54 55 bool transformFlagsAllEqual = m_SelectionFlagsArray.All(flags => (flags & TileFlags.LockTransform) == (m_SelectionFlagsArray.First() & TileFlags.LockTransform)); 56 if (!transformFlagsAllEqual || (m_SelectionFlagsArray[0] & TileFlags.LockTransform) != 0) 57 return; 58 59 var index = m_FirstCellWithTile != -1 ? m_FirstCellWithTile : 0; 60 var transformMatrix = m_SelectionMatrices[index]; 61 var p = (Vector3)transformMatrix.GetColumn(3); 62 var r = Quaternion.identity; 63 var s = transformMatrix.lossyScale; 64 Vector3 selectionPosition = GridSelection.position.position; 65 selectionPosition += tilemap.tileAnchor; 66 if (selectionCellCount > 1) 67 { 68 selectionPosition.x = GridSelection.position.center.x; 69 selectionPosition.y = GridSelection.position.center.y; 70 } 71 var gizmoPosition = tilemap.LocalToWorld(tilemap.CellToLocalInterpolated(selectionPosition)) + p; 72 var originalP = gizmoPosition; 73 var originalR = r; 74 var originalS = s; 75 EditorGUI.BeginChangeCheck(); 76 HandleTool(ref gizmoPosition, ref r, ref s); 77 if (EditorGUI.EndChangeCheck()) 78 { 79 Undo.RegisterCompleteObjectUndo(new Object[] { tilemap, tilemap.gameObject }, "Move"); 80 var deltaPos = gizmoPosition - originalP; 81 var deltaRotation = Quaternion.Inverse(originalR) * r; 82 var deltaScale = new Vector3(s.x / originalS.x, s.y / originalS.y, s.z / originalS.z); 83 foreach (var cellPosition in GridSelection.position.allPositionsWithin) 84 { 85 if (tilemap.HasTile(cellPosition)) 86 { 87 var trs = tilemap.GetTransformMatrix(cellPosition); 88 var tilePosition = trs.GetPosition() + deltaPos; 89 var tileRotation = trs.rotation * deltaRotation; 90 var tileScale = trs.lossyScale; 91 tileScale.x *= deltaScale.x; 92 tileScale.y *= deltaScale.y; 93 tileScale.z *= deltaScale.z; 94 trs = Matrix4x4.TRS(tilePosition, tileRotation, tileScale); 95 tilemap.SetTransformMatrix(cellPosition, trs); 96 } 97 } 98 InspectorWindow.RepaintAllInspectors(); 99 } 100 } 101 102 /// <summary> 103 /// Handles the gizmo for the GridSelectionTool. 104 /// Implement this the handle the gizmo for the GridSelectionTool. 105 /// </summary> 106 /// <param name="position">Position of the GridSelection gizmo.</param> 107 /// <param name="rotation">Rotation of the GridSelection gizmo.</param> 108 /// <param name="scale">Scale of the GridSelection gizmo.</param> 109 public abstract void HandleTool(ref Vector3 position, ref Quaternion rotation, ref Vector3 scale); 110 111 internal static bool IsActive() 112 { 113 return ToolManager.activeToolType != null && ToolManager.activeToolType.IsSubclassOf(typeof(GridSelectionTool)); 114 } 115 116 private void UpdateSelection(Tilemap tilemap) 117 { 118 m_FirstCellWithTile = -1; 119 var selection = GridSelection.position; 120 var cellCount = selectionCellCount; 121 if (m_SelectionTiles == null || m_SelectionTiles.Length != selectionCellCount) 122 { 123 m_SelectionTiles = new TileBase[cellCount]; 124 m_SelectionColors = new Color[cellCount]; 125 m_SelectionMatrices = new Matrix4x4[cellCount]; 126 m_SelectionFlagsArray = new TileFlags[cellCount]; 127 m_SelectionSprites = new Sprite[cellCount]; 128 m_SelectionColliderTypes = new Tile.ColliderType[cellCount]; 129 } 130 131 int index = 0; 132 foreach (var p in selection.allPositionsWithin) 133 { 134 m_SelectionTiles[index] = tilemap.GetTile(p); 135 m_SelectionColors[index] = tilemap.GetColor(p); 136 m_SelectionMatrices[index] = tilemap.GetTransformMatrix(p); 137 m_SelectionFlagsArray[index] = tilemap.GetTileFlags(p); 138 m_SelectionSprites[index] = tilemap.GetSprite(p); 139 m_SelectionColliderTypes[index] = tilemap.GetColliderType(p); 140 141 if (m_FirstCellWithTile == -1 && m_SelectionTiles[index] != null) 142 m_FirstCellWithTile = index; 143 index++; 144 } 145 } 146 } 147}