0
\$\begingroup\$

I am following this video tutorial on how to implement drag-to-select behavior like in an RTS. The only difference is, I'm using a tilemap.

The selection area is a square which I can drag to make it as big as I want, like in any top down RTS.

CodeMonkey in his video uses Physics2D.OverlapAreaAll to get a list of all colliders in the selected area. I want to use this to specifically see which "vegetation" tiles I've selected. However, no matter which vegetation tile I select, or how many, I always get one result - the vegetation tilemap itself.

You can clearly see from this picture that every grass tile and every tree tile have a collider around them, which is why this works, but how can I get exactly those that I selected?

tile colliders

Other than vegetation from the tilemap, I also want this to work with GameObjects that have Box2DColliders on them, and that works out of the box. I also made those MonoBehaviors inherit an interface called ISelectable, so I can only add to the selected list entities that have that inherit that interface. I tried to do the same with vegetation like so public class Vegetation : Tile, ISelectable but it doesn't work.

What am I missing? Can this even work on a specific tile basis?

\$\endgroup\$
0
1
\$\begingroup\$

We can use the Tilemap's Grid to convert the world-space bounds of our selection rectangle into grid coordinates within the map:

LayoutGrid grid = tilemap.layoutGrid;
Vector3Int bottomLeftCell = grid.WorldToCell(bottomLeft);
Vector3Int topRightCell = grid.WorldToCell(topRight);

Vector3Int min = Vector3Int.Min(bottomLeftCell, topRightCell);
Vector3Int max = Vector3Int.Max(bottomLeftCell, topRightCell);
Vector3Int size = max - min + Vector3Int.one;

BoundsInt bounds = new BoundsInt(min, size);

Then we can ask the Tilemap to give us an array of all tiles in those bounds:

TileBase[] tiles = tilemap.GetTilesBlock(bounds);

Now you can walk through this tile array to find the vegetation tiles you care about (say, gathering up all the ones that implement ISelectable). They don't strictly need colliders for this purpose, since you can detect them by position and tile type, in case that simplifies any of your physics scene.

You'll still use your physics queries to detect objects that aren't part of the tile map, and use this method to inspect the tiles.

\$\endgroup\$
2
  • \$\begingroup\$ What if I have two Tilemaps, let's say one for vegetation and other one for any other interactable/selectable tiles? Would I need to iterate through both Tilemaps seperately? \$\endgroup\$ Mar 20 at 18:37
  • 1
    \$\begingroup\$ It sounds like you've answered that question. The interactable tilemap will only be able to tell you about its own tiles, not tiles in other tilemaps. But if they're sharing the same grid, you can use the same bounds for both queries. \$\endgroup\$
    – DMGregory
    Mar 20 at 18:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.