0
\$\begingroup\$

I have a tilemap that is filled with tiles by script. That works well so far. Now my aim is to make the tiles interactable by making them clickable.

I achieved this by adding an EventSystem object under the tilemap, adding a Physics 2D Raycaster component to the camera and then impementing IPointerDownHandler.OnPointerDown(..) in my script.

But here is the problem: I need to get the tile at the position that is clicked. As far as I read, this should easily be possible by calling the tilemaps WorldToCell function and then using the cell position to get the tile from the tilemap. However WorldToCell does only return me the floored world position instead of the cell position inside the tilemap.

My OnPointerDown function looks like this:

void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
{
    Debug.Log("Clicked at " + eventData.position.x + ", " + eventData.position.y);

    Tilemap tilemap = gameObject.GetComponent<Tilemap>();
    Vector3Int cellPos = tilemap.WorldToCell(new Vector3(eventData.position.x, eventData.position.y, 0));
    Debug.Log("Clicked at " + cellPos.x + ", " + cellPos.y);
}

If I click on a tile then then output on console looks like this:

Clicked at 1379,554, 275,0186
Clicked at 1379, 275

Can someone tell me what I got wrong or how WorldToCell actually works? I searched far and wide but none seems to have the same problem.

\$\endgroup\$
1
  • \$\begingroup\$ World to Cell does convert from world coordinates to tile coordinates. For some grid settings, that conversion is as simple as flooring. Can you explain in more detail what leads you to believe these numbers differ from the numbers you need? What desired output would you expect to see instead? \$\endgroup\$
    – DMGregory
    May 26 at 10:14

1 Answer 1

2
\$\begingroup\$

PointerEcentData.position is a screen position rather than a world position. See EventSystems.PointerEventData-position :

The position value is window-based. This is zero-zero bottom left.

So you can convert it to world postiion first, using Camera.ScreenToWorldPoint :

var worldPos = Camera.main.ScreenToWorldPoint(eventData.position);
Vector3Int cellPos = tilemap.WorldToCell(worldPos);
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Note that if you're using a perspective camera or a tilted orthographic camera, you'll want to choose a non-zero z value for your screen position before passing it to ScreenToWorldPoint \$\endgroup\$
    – DMGregory
    May 26 at 10:17
  • \$\begingroup\$ Now everything makes sense (and also works). Thank you very much! \$\endgroup\$
    – Evg
    May 26 at 11:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .