# Place tiles along a specific axis / direction

I want to be able to place tiles only in the direction I've started "drawing" them.

For an example, if I click and hold on tile at position (0,0), and start dragging to the right, I only want to select or draw on coordinates (1,0), (2,0), (3,0) and so on. However, for the next tile, if I point my mouse at the tile (4,1), I only want (4,0) to be selected, aka, ignore the Y changes because I'm currently placing on the X axis.

What would be a good and clean way to do this?

I've tried doing this but not only does it not work well, my code is very bloated because I'm not good at this logic that requires more math than usual. Here's what I tried (needless to say it's very messy and didn't work properly):

private bool isSelecting;
private Vector3Int selectionDirection = Vector3Int.zero;
public List<Vector3Int> selectedPositions = new List<Vector3Int>();
private SelectDirect selectDirect;

if (Mouse.current.leftButton.wasPressedThisFrame)
{
if (UIManager.IsMouseOverUI()) { return; }

Vector3Int gridPosition = Map.GetGridPosFromMousePos();

if (Map.IsInsideMap(gridPosition))
{
if (!selectedPositions.Contains(gridPosition)) { selectedPositions.Add(gridPosition); }
isSelecting = true;
}
}

if (Mouse.current.leftButton.wasReleasedThisFrame)
{
isSelecting = false;
selectedPositions.Clear();
selectionDirection = Vector3Int.zero;
selectDirect = SelectDirect.None;
}

if (isSelecting)
{
if (selectionDirection == Vector3Int.zero && selectedPositions.Count == 2)
{
selectionDirection = selectedPositions[1] - selectedPositions[0];

if (Mathf.Abs(selectionDirection.x) + Mathf.Abs(selectionDirection.y) > 1)
{
isSelecting = false;
selectedPositions.Clear();
selectionDirection = Vector3Int.zero;
selectDirect = SelectDirect.None;
return;
}

if (selectionDirection.x == 1) { selectDirect = SelectDirect.Right; }
else { selectDirect = SelectDirect.Up; }

Debug.Log(selectDirect);
}

Vector3Int gridPosition = Map.GetGridPosFromMousePos();

if (Map.IsInsideMap(gridPosition))
{
switch (selectDirect)
{
case SelectDirect.None:
if (!selectedPositions.Contains(gridPosition)) { selectedPositions.Add(gridPosition); }
break;
case SelectDirect.Right:
if (gridPosition.x - selectedPositions[selectedPositions.Count - 1].x == Mathf.Abs(selectionDirection.x) && !selectedPositions.Contains(gridPosition))
{
selectedPositions.Add(gridPosition);
}
break;
case SelectDirect.Up:
if (gridPosition.y - selectedPositions[selectedPositions.Count - 1].y == Mathf.Abs(selectionDirection.y) && !selectedPositions.Contains(gridPosition))
{
selectedPositions.Add(gridPosition);
}
break;
}
}
}


## 1 Answer

Some semi pseudo code

• Change SelectDirect.Up to SelectDirect.Vertical and SelectDirect.Right to SelectDirect.Horizontal

• if (Mathf.Abs(selectionDirection.x) == 1) {
selectDirect = SelectDirect.Horizontal;
fixedY = selectedPositions[0].y;
}

• On the case switch Horizontal you can compare SelectedPiece.position vs Vector2(SelectedPiece.x, fixedY). This should work for left movement without extra code.

• Vertical is going to work the same, just comparing against a stored x value;

You are storing either the initial x or y value of your first selected tile. After drawing a horizontal line, if the selected tile has not the same y value as the original one, the line is not straight and gets discarded. You can fine tune this later if you want with a small toleranz of maybe 1 tile (to add the intended tile) by setting the fixed value instead of the current selected.