public void SetTileData(Vector2 vLocalPos, int tileId, int brushId = Tileset.k_BrushId_Default, eTileFlags flags = eTileFlags.None) { int gridX = BrushUtil.GetGridX(vLocalPos, CellSize); int gridY = BrushUtil.GetGridY(vLocalPos, CellSize); SetTileData(gridX, gridY, tileId, brushId, flags); }
/// <summary> /// Return the tile at the local position /// </summary> /// <param name="vLocalPos"></param> /// <returns></returns> public Tile GetTile(Vector2 vLocalPos) { int gridX = BrushUtil.GetGridX(vLocalPos, CellSize); int gridY = BrushUtil.GetGridY(vLocalPos, CellSize); return(GetTile(gridX, gridY)); }
public static void FloodFill(Tilemap tilemap, Vector2 vLocalPos, uint[,] tileData) { int gridX = BrushUtil.GetGridX(vLocalPos, tilemap.CellSize); int gridY = BrushUtil.GetGridY(vLocalPos, tilemap.CellSize); FloodFill(tilemap, gridX, gridY, tileData); }
/// <summary> /// Set a tile data using a tilemap local position /// </summary> /// <param name="vLocalPos"></param> /// <param name="tileData"></param> public void SetTileData(Vector2 vLocalPos, uint tileData) { int gridX = BrushUtil.GetGridX(vLocalPos, CellSize); int gridY = BrushUtil.GetGridY(vLocalPos, CellSize); SetTileData(gridX, gridY, tileData); }
/// <summary> /// Gets the tile colors set for the tile at local position /// </summary> /// <param name="vLocalPos"></param> /// <returns></returns> public Color32[] GetTileColor(Vector2 vLocalPos) { int gridX = BrushUtil.GetGridX(vLocalPos, CellSize); int gridY = BrushUtil.GetGridY(vLocalPos, CellSize); return(GetTileColor(gridX, gridY)); }
public static void FloodFillPreview(Tilemap tilemap, Vector2 vLocalPos, uint tileData, List <Vector2> outFilledPoints, uint maxPoints = uint.MaxValue) { int gridX = BrushUtil.GetGridX(vLocalPos, tilemap.CellSize); int gridY = BrushUtil.GetGridY(vLocalPos, tilemap.CellSize); FloodFillPreview(tilemap, gridX, gridY, tileData, outFilledPoints, maxPoints); }
/// <summary> /// Shrink the map bounds to the minimum area enclosing all visible tiles /// </summary> public void ShrinkMapBoundsToVisibleArea() { Bounds mapBounds = new Bounds(); Vector2 halfCellSize = CellSize / 2f; // used to avoid precission errors m_maxGridX = m_maxGridY = m_minGridX = m_minGridY = 0; var valueIter = m_dicChunkCache.Values.GetEnumerator(); while (valueIter.MoveNext()) { TilemapChunk chunk = valueIter.Current; if (chunk) { Bounds tilechunkBounds = chunk.GetBounds(); Vector2 min = transform.InverseTransformPoint(chunk.transform.TransformPoint(tilechunkBounds.min)); Vector2 max = transform.InverseTransformPoint(chunk.transform.TransformPoint(tilechunkBounds.max)); mapBounds.Encapsulate(min + halfCellSize); mapBounds.Encapsulate(max - halfCellSize); } } m_minGridX = BrushUtil.GetGridX(mapBounds.min, CellSize); m_minGridY = BrushUtil.GetGridY(mapBounds.min, CellSize); m_maxGridX = BrushUtil.GetGridX(mapBounds.max, CellSize); m_maxGridY = BrushUtil.GetGridY(mapBounds.max, CellSize); RecalculateMapBounds(); }
/// <summary> /// Set a tile color using a tilemap local position /// </summary> /// <param name="vLocalPos"></param> /// <param name="c0">Bottom left corner</param> /// <param name="c1">Bottom right corner</param> /// <param name="c2">Top left corner</param> /// <param name="c3">Top right corner</param> public void SetTileColor(Vector2 vLocalPos, Color32 c0, Color32 c1, Color32 c2, Color32 c3) { int gridX = BrushUtil.GetGridX(vLocalPos, CellSize); int gridY = BrushUtil.GetGridY(vLocalPos, CellSize); SetTileColor(gridX, gridY, c0, c1, c2, c3); }
/// <summary> /// Set a tile color using a tilemap local position /// </summary> /// <param name="vLocalPos"></param> /// <param name="c0">Bottom left corner</param> /// <param name="c1">Bottom right corner</param> /// <param name="c2">Top left corner</param> /// <param name="c3">Top right corner</param> public void SetTileColor(Vector2 vLocalPos, TileColor32 tileColor, eBlendMode blendMode = eBlendMode.AlphaBlending) { int gridX = BrushUtil.GetGridX(vLocalPos, CellSize); int gridY = BrushUtil.GetGridY(vLocalPos, CellSize); SetTileColor(gridX, gridY, tileColor, blendMode); }
public void Paint(Tilemap tilemap, Vector2 localPos) { int minGridX = m_brushTilemap.MinGridX; int minGridY = m_brushTilemap.MinGridY; int maxGridX = m_brushTilemap.MaxGridX; int maxGridY = m_brushTilemap.MaxGridY; if (IsUndoEnabled) { #if UNITY_EDITOR Undo.RecordObject(tilemap, Tilemap.k_UndoOpName + tilemap.name); Undo.RecordObjects(tilemap.GetComponentsInChildren <TilemapChunk>(), Tilemap.k_UndoOpName + tilemap.name); #endif } tilemap.IsUndoEnabled = IsUndoEnabled; int dstGy = BrushUtil.GetGridY(localPos, tilemap.CellSize); for (int gridY = minGridY; gridY <= maxGridY; ++gridY, ++dstGy) { int dstGx = BrushUtil.GetGridX(localPos, tilemap.CellSize); for (int gridX = minGridX; gridX <= maxGridX; ++gridX, ++dstGx) { uint tileData = m_brushTilemap.GetTileData(gridX, gridY); if ( tileData != Tileset.k_TileData_Empty || // don't copy empty tiles m_brushTilemap.GridWidth == 1 && m_brushTilemap.GridHeight == 1 // unless the brush size is one ) { tilemap.SetTileData(dstGx, dstGy, tileData); } } } tilemap.UpdateMeshImmediate(); tilemap.IsUndoEnabled = false; }
public void Erase(Tilemap tilemap, Vector2 localPos) { int minGridX = m_brushTilemap.MinGridX; int minGridY = m_brushTilemap.MinGridY; int maxGridX = m_brushTilemap.MaxGridX; int maxGridY = m_brushTilemap.MaxGridY; if (IsUndoEnabled) { #if UNITY_EDITOR Undo.RecordObject(tilemap, Tilemap.k_UndoOpName + tilemap.name); Undo.RecordObjects(tilemap.GetComponentsInChildren <TilemapChunk>(), Tilemap.k_UndoOpName + tilemap.name); #endif } tilemap.IsUndoEnabled = IsUndoEnabled; int dstGy = BrushUtil.GetGridY(localPos, tilemap.CellSize); for (int gridY = minGridY; gridY <= maxGridY; ++gridY, ++dstGy) { int dstGx = BrushUtil.GetGridX(localPos, tilemap.CellSize); for (int gridX = minGridX; gridX <= maxGridX; ++gridX, ++dstGx) { tilemap.SetTileData(dstGx, dstGy, Tileset.k_TileData_Empty); } } tilemap.UpdateMeshImmediate(); tilemap.IsUndoEnabled = false; }
public void Rot90(bool changeFlags = true) { int gridX = BrushUtil.GetGridX(-Offset, m_brushTilemap.CellSize); int gridY = BrushUtil.GetGridY(-Offset, m_brushTilemap.CellSize); Offset = -new Vector2(gridY * m_brushTilemap.CellSize.x, (m_brushTilemap.GridWidth - gridX - 1) * m_brushTilemap.CellSize.y); m_brushTilemap.Rot90(changeFlags); m_brushTilemap.UpdateMeshImmediate(); }
public void Rot90Back(bool changeFlags = true) { //NOTE: This is a fast way to rotate back 90º by rotating forward 3 times for (int i = 0; i < 3; ++i) { int gridX = BrushUtil.GetGridX(-Offset, m_brushTilemap.CellSize); int gridY = BrushUtil.GetGridY(-Offset, m_brushTilemap.CellSize); Offset = -new Vector2(gridY * m_brushTilemap.CellSize.x, (m_brushTilemap.GridWidth - gridX - 1) * m_brushTilemap.CellSize.y); m_brushTilemap.Rot90(changeFlags); } m_brushTilemap.UpdateMeshImmediate(); }
public void Paint(STETilemap tilemap, Vector2 localPos, bool skipEmptyTiles = false) { int minGridX = m_brushTilemap.MinGridX; int minGridY = m_brushTilemap.MinGridY; int maxGridX = m_brushTilemap.MaxGridX; int maxGridY = m_brushTilemap.MaxGridY; if (IsUndoEnabled) { #if UNITY_EDITOR Undo.RecordObject(tilemap, STETilemap.k_UndoOpName + tilemap.name); Undo.RecordObjects(tilemap.GetComponentsInChildren <TilemapChunk>(), STETilemap.k_UndoOpName + tilemap.name); #endif } tilemap.IsUndoEnabled = IsUndoEnabled; int dstGy = BrushUtil.GetGridY(localPos, tilemap.CellSize); bool doPaintEmpty = m_brushTilemap.GridWidth == 1 && m_brushTilemap.GridHeight == 1 || // don't copy empty tiles m_brushPattern != null && m_brushPattern.GetLength(0) == 1 && m_brushPattern.GetLength(1) == 1;// unless the brush size is one doPaintEmpty &= !skipEmptyTiles; TileObjSourceTilemap = BrushTilemap; TileObjSourceTilemapOffset = new Vector2Int(-BrushUtil.GetGridX(localPos, tilemap.CellSize), -dstGy); for (int gridY = minGridY; gridY <= maxGridY; ++gridY, ++dstGy) { int dstGx = BrushUtil.GetGridX(localPos, tilemap.CellSize); for (int gridX = minGridX; gridX <= maxGridX; ++gridX, ++dstGx) { uint tileData = m_brushTilemap.GetTileData(gridX, gridY); if ( doPaintEmpty || tileData != Tileset.k_TileData_Empty ) { tilemap.SetTileData(dstGx, dstGy, tileData); } } } tilemap.UpdateMeshImmediate(); TileObjSourceTilemap = null; tilemap.IsUndoEnabled = false; }
public void DoPaintReleased(STETilemap tilemap, Vector2 localPos, EventModifiers modifiers = default(EventModifiers)) { //Debug.Log("DoPaintReleased (" + TilemapUtils.GetGridX(tilemap, localPos) + "," + TilemapUtils.GetGridY(tilemap, localPos) + ")"); if (m_paintMode != eBrushPaintMode.Pencil) { Vector2 pressedPos = BrushUtil.GetSnappedPosition(m_pressedPosition, BrushTilemap.CellSize) + BrushTilemap.CellSize / 2f; Paint(tilemap, pressedPos + (Vector2)BrushTilemap.MapBounds.min, true); m_pressedPosition = localPos; BrushTilemap.ClearMap(); for (int y = 0; y < m_brushPattern.GetLength(1); ++y) { for (int x = 0; x < m_brushPattern.GetLength(0); ++x) { BrushTilemap.SetTileData(x, y, m_brushPattern[x, y]); } } BrushTilemap.UpdateMesh(); m_isDragging = false; } }
/// <summary> /// Shrink the map bounds to the minimum area enclosing all visible tiles /// </summary> public void ShrinkMapBoundsToVisibleArea() { Bounds mapBounds = new Bounds(); Vector2 halfCellSize = CellSize / 2f; // used to avoid precission errors m_maxGridX = m_maxGridY = m_minGridX = m_minGridY = 0; foreach (TilemapChunk chunk in m_dicChunkCache.Values) { if (chunk) { Bounds tilechunkBounds = chunk.GetBounds(); Vector2 min = transform.InverseTransformPoint(chunk.transform.TransformPoint(tilechunkBounds.min)); Vector2 max = transform.InverseTransformPoint(chunk.transform.TransformPoint(tilechunkBounds.max)); mapBounds.Encapsulate(min + halfCellSize); mapBounds.Encapsulate(max - halfCellSize); } } m_minGridX = BrushUtil.GetGridX(mapBounds.min, CellSize); m_minGridY = BrushUtil.GetGridY(mapBounds.min, CellSize); m_maxGridX = BrushUtil.GetGridX(mapBounds.max, CellSize); m_maxGridY = BrushUtil.GetGridY(mapBounds.max, CellSize); RecalculateMapBounds(); }
/// <summary> /// Shrink the map bounds to the minimum area enclosing all visible tiles /// </summary> public void ShrinkMapBoundsToVisibleArea() { Bounds mapBounds = new Bounds(); Vector2 halfCellSize = CellSize / 2f; // used to avoid precission errors m_maxGridX = m_maxGridY = m_minGridX = m_minGridY = 0; for (int i = 0; i < transform.childCount; ++i) { TilemapChunk chunk = transform.GetChild(i).GetComponent <TilemapChunk>(); if (chunk != null) { Bounds tilechunkBounds = chunk.MeshFilter.sharedMesh.bounds; Vector2 min = transform.InverseTransformPoint(chunk.transform.TransformPoint(tilechunkBounds.min)); Vector2 max = transform.InverseTransformPoint(chunk.transform.TransformPoint(tilechunkBounds.max)); mapBounds.Encapsulate(min + halfCellSize); mapBounds.Encapsulate(max - halfCellSize); } } m_minGridX = BrushUtil.GetGridX(mapBounds.min, CellSize); m_minGridY = BrushUtil.GetGridY(mapBounds.min, CellSize); m_maxGridX = BrushUtil.GetGridX(mapBounds.max, CellSize); m_maxGridY = BrushUtil.GetGridY(mapBounds.max, CellSize); RecalculateMapBounds(); }
public static int GetGridPosHashCode(Vector2 position, Vector2 cellSize) { return(GetGridPosHashCode(BrushUtil.GetGridX(position, cellSize), BrushUtil.GetGridY(position, cellSize))); }
public MapTileNode GetMapTileNode(Vector2 position) { return(GetMapTileNode(BrushUtil.GetGridX(position, CellSize), BrushUtil.GetGridY(position, CellSize))); }
static public int GetGridY(Vector2 locPosition, Vector2 cellSize) { return(BrushUtil.GetGridY(locPosition, cellSize)); }
private void DoPaintInspector() { Event e = Event.current; Tilemap tilemap = (Tilemap)target; if (DoToolBar() || DragAndDrop.objectReferences.Length > 0 || // hide brush when user is dragging a prefab into the scene EditorWindow.mouseOverWindow != SceneView.currentDrawingSceneView) // hide brush when it's not over the scene view { m_brushVisible = false; SceneView.RepaintAll(); return; } int controlID = GUIUtility.GetControlID(FocusType.Passive); HandleUtility.AddDefaultControl(controlID); EventType currentEventType = Event.current.GetTypeForControl(controlID); bool skip = false; int saveControl = GUIUtility.hotControl; try { if (currentEventType == EventType.Layout) { skip = true; } else if (currentEventType == EventType.ScrollWheel) { skip = true; } if (tilemap.Tileset == null) { return; } if (!skip) { if (e.type == EventType.KeyDown) { if (e.keyCode == ShortcutKeys.k_FlipH) { BrushBehaviour.GetOrCreateBrush(tilemap).FlipH(!e.shift); e.Use(); // Use key event } else if (e.keyCode == ShortcutKeys.k_FlipV) { BrushBehaviour.GetOrCreateBrush(tilemap).FlipV(!e.shift); e.Use(); // Use key event } else if (e.keyCode == ShortcutKeys.k_Rot90) { BrushBehaviour.GetOrCreateBrush(tilemap).Rot90(!e.shift); e.Use(); // Use key event } else if (e.keyCode == ShortcutKeys.k_Rot90Back) { BrushBehaviour.GetOrCreateBrush(tilemap).Rot90Back(!e.shift); e.Use(); // Use key event } } EditorGUIUtility.AddCursorRect(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), MouseCursor.Arrow); GUIUtility.hotControl = controlID; { Plane chunkPlane = new Plane(tilemap.transform.forward, tilemap.transform.position); Vector2 mousePos = Event.current.mousePosition; mousePos.y = Screen.height - mousePos.y; Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); float dist; if (chunkPlane.Raycast(ray, out dist)) { Rect rTile = new Rect(0, 0, m_tilemap.CellSize.x, m_tilemap.CellSize.y); rTile.position = tilemap.transform.InverseTransformPoint(ray.GetPoint(dist)); Vector2 tilePos = rTile.position; if (tilePos.x < 0) { tilePos.x -= m_tilemap.CellSize.x; } if (tilePos.y < 0) { tilePos.y -= m_tilemap.CellSize.y; } tilePos.x -= tilePos.x % m_tilemap.CellSize.x; tilePos.y -= tilePos.y % m_tilemap.CellSize.y; rTile.position = tilePos; Vector2 startPos = new Vector2(Mathf.Min(m_startDragging.x, m_endDragging.x), Mathf.Min(m_startDragging.y, m_endDragging.y)); Vector2 endPos = new Vector2(Mathf.Max(m_startDragging.x, m_endDragging.x), Mathf.Max(m_startDragging.y, m_endDragging.y)); Vector2 selectionSnappedPos = BrushUtil.GetSnappedPosition(startPos, m_tilemap.CellSize); Vector2 selectionSize = BrushUtil.GetSnappedPosition(endPos, m_tilemap.CellSize) - selectionSnappedPos + m_tilemap.CellSize; BrushBehaviour brush = BrushBehaviour.GetOrCreateBrush(tilemap); // Update brush transform m_localPaintPos = (Vector2)tilemap.transform.InverseTransformPoint(ray.GetPoint(dist)); Vector2 brushSnappedPos = BrushUtil.GetSnappedPosition(brush.Offset + m_localPaintPos, m_tilemap.CellSize); brush.transform.rotation = tilemap.transform.rotation; brush.transform.localScale = tilemap.transform.lossyScale; brush.transform.position = tilemap.transform.TransformPoint(new Vector3(brushSnappedPos.x, brushSnappedPos.y, -0.01f)); //--- int prevMouseGridX = m_mouseGridX; int prevMouseGridY = m_mouseGridY; if (e.isMouse) { m_mouseGridX = BrushUtil.GetGridX(m_localPaintPos, tilemap.CellSize); m_mouseGridY = BrushUtil.GetGridY(m_localPaintPos, tilemap.CellSize); } bool isMouseGridChanged = prevMouseGridX != m_mouseGridX || prevMouseGridY != m_mouseGridY; //Update Fill Preview if (GetBrushMode() == eBrushMode.Fill && isMouseGridChanged) { m_fillPreview.Clear(); TilemapDrawingUtils.FloodFillPreview(tilemap, brush.Offset + m_localPaintPos, brush.BrushTilemap.GetTileData(0, 0), m_fillPreview); } if ( (EditorWindow.focusedWindow == EditorWindow.mouseOverWindow) && // fix painting tiles when closing another window popup over the SceneView like GameObject Selection window (e.type == EventType.MouseDown || e.type == EventType.MouseDrag && isMouseGridChanged) ) { if (e.button == 0) { if (m_dblClick.IsDblClick && brush.BrushTilemap.GridWidth == 1 && brush.BrushTilemap.GridHeight == 1) { // Restore previous tiledata modified by Paint, because before the double click, a single click is done before tilemap.SetTileData(brush.Offset + m_localPaintPos, m_floodFillRestoredTileData); brush.FloodFill(tilemap, brush.Offset + m_localPaintPos, brush.BrushTilemap.GetTileData(0, 0)); } // Do a brush paint action else { switch (GetBrushMode()) { case eBrushMode.Paint: m_floodFillRestoredTileData = tilemap.GetTileData(m_mouseGridX, m_mouseGridY); brush.Paint(tilemap, brush.Offset + m_localPaintPos); break; case eBrushMode.Erase: brush.Erase(tilemap, brush.Offset + m_localPaintPos); break; case eBrushMode.Fill: brush.FloodFill(tilemap, brush.Offset + m_localPaintPos, brush.BrushTilemap.GetTileData(0, 0)); break; } } } else if (e.button == 1) { if (e.type == EventType.MouseDown) { m_isDragging = true; brush.BrushTilemap.ClearMap(); m_startDragging = m_endDragging = m_localPaintPos; } else { m_endDragging = m_localPaintPos; } } } else if (e.type == EventType.MouseUp) { if (e.button == 1) // right mouse button { m_isDragging = false; ResetBrushMode(); // Copy one tile if (selectionSize.x <= m_tilemap.CellSize.x && selectionSize.y <= m_tilemap.CellSize.y) { uint tileData = tilemap.GetTileData(m_localPaintPos); if (tileData == Tileset.k_TileData_Empty) { tilemap.Tileset.SelectedTileId = Tileset.k_TileId_Empty; brush.BrushTilemap.SetTileData(0, 0, Tileset.k_TileData_Empty); } else { int brushId = Tileset.GetBrushIdFromTileData(tileData); int tileId = Tileset.GetTileIdFromTileData(tileData); // Select the copied tile in the tileset, alternating between the brush and the tile drawn by the brush if (brushId > 0 && brushId != tilemap.Tileset.SelectedBrushId) { tilemap.Tileset.SelectedBrushId = brushId; } else { tilemap.Tileset.SelectedTileId = tileId; brush.BrushTilemap.SetTileData(0, 0, tileData & ~Tileset.k_TileDataMask_BrushId); // keep tile flags } } // Cut tile if key shift is pressed if (e.shift) { int startGridX = BrushUtil.GetGridX(startPos, m_tilemap.CellSize); int startGridY = BrushUtil.GetGridY(startPos, m_tilemap.CellSize); brush.CutRect(tilemap, startGridX, startGridY, startGridX, startGridY); } brush.BrushTilemap.UpdateMesh(); brush.Offset = Vector2.zero; } // copy a rect of tiles else { int startGridX = BrushUtil.GetGridX(startPos, m_tilemap.CellSize); int startGridY = BrushUtil.GetGridY(startPos, m_tilemap.CellSize); int endGridX = BrushUtil.GetGridX(endPos, m_tilemap.CellSize); int endGridY = BrushUtil.GetGridY(endPos, m_tilemap.CellSize); // Cut tile if key shift is pressed if (e.shift) { brush.CutRect(tilemap, startGridX, startGridY, endGridX, endGridY); } else { brush.CopyRect(tilemap, startGridX, startGridY, endGridX, endGridY); } brush.Offset.x = m_endDragging.x > m_startDragging.x ? -(endGridX - startGridX) * tilemap.CellSize.x : 0f; brush.Offset.y = m_endDragging.y > m_startDragging.y ? -(endGridY - startGridY) * tilemap.CellSize.y : 0f; } } } if (m_isDragging) { Rect rGizmo = new Rect(selectionSnappedPos, selectionSize); HandlesEx.DrawRectWithOutline(tilemap.transform, rGizmo, new Color(), Color.white); } else // Draw brush border { Rect rBound = new Rect(brush.BrushTilemap.MapBounds.min, brush.BrushTilemap.MapBounds.size); Color fillColor; switch (GetBrushMode()) { case eBrushMode.Paint: fillColor = new Color(0, 0, 0, 0); break; case eBrushMode.Erase: fillColor = new Color(1f, 0f, 0f, 0.1f); break; case eBrushMode.Fill: fillColor = new Color(1f, 1f, 0f, 0.2f); break; default: fillColor = new Color(0, 0, 0, 0); break; } HandlesEx.DrawRectWithOutline(brush.transform, rBound, fillColor, new Color(1, 1, 1, 0.2f)); } } } if (currentEventType == EventType.MouseDrag && Event.current.button < 2) // 2 is for central mouse button { // avoid dragging the map Event.current.Use(); } } } // Avoid loosing the hotControl because of a triggered exception catch (System.Exception ex) { Debug.LogException(ex); } SceneView.RepaintAll(); GUIUtility.hotControl = saveControl; }
public void DoPaintDragged(STETilemap tilemap, Vector2 localPos, EventModifiers modifiers = default(EventModifiers)) { //Debug.Log("DoPaintDragged (" + TilemapUtils.GetGridX(tilemap, localPos) + "," + TilemapUtils.GetGridY(tilemap, localPos) + ")"); bool isSingleEmptyTile = BrushTilemap.GridWidth == 1 && BrushTilemap.GridHeight == 1 && BrushTilemap.GetTileData(0, 0) == Tileset.k_TileData_Empty; if (m_paintMode == eBrushPaintMode.Pencil || isSingleEmptyTile) { Paint(tilemap, localPos); } else { if (m_isDragging) { BrushTilemap.ClearMap(); Vector2 brushLocPos = tilemap.transform.InverseTransformPoint(transform.position); Vector2 startPos = BrushUtil.GetSnappedPosition(m_pressedPosition, BrushTilemap.CellSize) + BrushTilemap.CellSize / 2f - brushLocPos; Vector2 endPos = BrushUtil.GetSnappedPosition(localPos, BrushTilemap.CellSize) + BrushTilemap.CellSize / 2f - brushLocPos; bool isCtrl = (modifiers & EventModifiers.Control) != 0; bool isShift = (modifiers & EventModifiers.Shift) != 0; switch (m_paintMode) { case eBrushPaintMode.Line: if (isCtrl) { TilemapDrawingUtils.DrawLineMirrored(BrushTilemap, startPos, endPos, m_brushPattern); } else { TilemapDrawingUtils.DrawLine(BrushTilemap, startPos, endPos, m_brushPattern); } break; case eBrushPaintMode.Rect: case eBrushPaintMode.FilledRect: case eBrushPaintMode.Ellipse: case eBrushPaintMode.FilledEllipse: if (isShift) { Vector2 vTemp = endPos - startPos; float absX = Mathf.Abs(vTemp.x); float absY = Mathf.Abs(vTemp.y); vTemp.x = (absX > absY) ? vTemp.x : Mathf.Sign(vTemp.x) * absY; vTemp.y = Mathf.Sign(vTemp.y) * Mathf.Abs(vTemp.x); endPos = startPos + vTemp; } if (isCtrl) { startPos = 2f * startPos - endPos; } if (m_paintMode == eBrushPaintMode.Rect || m_paintMode == eBrushPaintMode.FilledRect) { TilemapDrawingUtils.DrawRect(BrushTilemap, startPos, endPos, m_brushPattern, m_paintMode == eBrushPaintMode.FilledRect, (modifiers & EventModifiers.Alt) != 0); } else if (m_paintMode == eBrushPaintMode.Ellipse || m_paintMode == eBrushPaintMode.FilledEllipse) { TilemapDrawingUtils.DrawEllipse(BrushTilemap, startPos, endPos, m_brushPattern, m_paintMode == eBrushPaintMode.FilledEllipse); } break; } BrushTilemap.UpdateMeshImmediate(); } } }
/// <summary> /// Gets the grid Y position for a given tilemap and local position. To convert from world to local position use tilemap.transform.InverseTransformPoint(worldPosition). /// Avoid using positions multiple of cellSize like 0.32f if cellSize = 0.16f because due float imprecisions the return value could be wrong. /// </summary> /// <param name="tilemap"></param> /// <param name="locPosition"></param> /// <returns></returns> static public int GetGridY(STETilemap tilemap, Vector2 locPosition) { return(BrushUtil.GetGridY(locPosition, tilemap.CellSize)); }