- Home /
Finding the position of a tile on a tilemap using Physics.Raycast2D.
What I want to do is to do a Ray cast from a position above a tile and see if a tile is within the raycast distance. If there is a tile want to get it's POSITION ON THE GRID as a co-ordinate. (eg: 14, 5 - row 14 column 5) My code is below. I have spent about two days trying various methods. Nothing has worked.
private void Update ( )
{
Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector3Int cO = foreground.WorldToCell(mouseWorldPos);
RaycastHit2D rayInfo;
rayInfo = Physics2D.Raycast ( new Vector2 ( mouseWorldPos.x, mouseWorldPos.y ), transform.up, -3f, LayerMask.GetMask ( "Ground" ) );
if ( rayInfo.collider == null && Input.GetMouseButtonDown(0) )
{
foreground.SetTile ( cO , waterTile );
Debug.Log ( "No col" + cO );
}
else if( rayInfo.collider != null && Input.GetMouseButtonDown ( 0 ) )
{
Vector3 cellHitByRay =(foreground.WorldToCell(rayInfo.transform.position));
//Vector3Int newYpos = foreground.WorldToCell(belowTP);
Debug.Log ( "COLLISION :" + cellHitByRay );
Vector3 diff = mouseWorldPos - cellHitByRay;
//Vector3 newYPos = mouseWorldPos + (new Vector3 (0, 6, 0) -diff);
}
}
In addition to what highpockets already said, some more information would be useful, what is happening when you try to run the project? What gets printed by Debug.Log, how does this differ from what you WANT it to do?
Debug.Log ( "COLLISION :" + cellHitByRay ); returns 0.0, 0.0, 0. I suspect this is the transform of the entire tilemap named foreground. When I moved it to a different position and tried my guess wad proved. The result gives the transform position of the tile map and NOT the specific tile. I want the position of the exact tile that I am hitting with my raycast.
Answer by Nikola7007 · May 28, 2019 at 06:45 PM
If the tilemap is directly perpendicular to the camera, then what you are already doing:
Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector3Int cO = foreground.WorldToCell(mouseWorldPos);
should be sufficient to find the tile coordinate which the mouse was pointing to. Alternatively, you might want to use RaycastHit2D.point and then convert that point to tilemap coordinates using foreground.WorldToCell(rayInfo.point) or something along those lines.
I would use this solution. Though you will likely need to test the raycast hit.point against your tile map array of positions by looping through the cell positions and finding which cell is closest to the hit.point.
Thing is, tilemap.WorldToCell() should already do exactly that, right? Convert a world point to a tilemap cell. I can't figure out what's the problem with OP's approach
I’ve never used the tile map or WorldToCell(), but the API says it converts a world position to a cell position. So I guess that this just finds the closest cell position to the world coordinates which are passed. That should be kind of what he is looking for, but it looks like he only wants this to happen if the mousePosition is within a certain range, hence the 3 unit distance on his raycast, but this would still work if you just check the magnitude from the world position to the cell position
@ Nikola7007, The code below worked correct but I have to subtract 1 from the answer to get the correct tile. $$anonymous$$y need is fulfilled but why do I have to subtract 1?
else if( rayInfo.collider != null && Input.Get$$anonymous$$ouseButtonDown ( 0 ) )
{
Vector3 cellHitByRay =(Camera.main.ScreenToWorldPoint(rayInfo.transform.position));
Vector3Int newYpos = foreground.WorldToCell(rayInfo.point);
Debug.Log ( "COLLISION :" + newYpos);
When I click below the tile in question the answer was "No col" (11, 6, 0) but when I clicked 3 tiles above it the answer was COLLISION(11,8,0). So obviously the tile position is (11,7,0). I can always subtract 1 but why is this?
This is just a guess but I would think that the ray intersection point is right on the border between the two tiles; maybe by default, if you're right on the border, the point is considered part of the upper tile. You could test this by adding, say, 0.1 unit downwards to rayInfo.point before passing it to WorldToCell()
. Also, I should mention, discussion or clarification on an answer should generally be done in comments, not as separate Answers, AFAI$$anonymous$$.
Your suggestions work as stated. oops! Sorry, I missed the correct thread.
Your answer
![](https://koobas.hobune.stream/wayback/20220612202241im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Painting Prefabs with Tile Palette (Inefficiency && Offset Problem) 0 Answers
How to use tilemaps? 0 Answers