0
\$\begingroup\$

I'm using mouse input to move the player from where they are to where the mouse position is relative to the cell on a tilemap. However I found when I click on a point of the tilemap, the z coordinate for it is -10. This has led to me to dealing with a work around of just resetting the player's z coordinate every time they are moved. I was wondering why this is the case and if there is a way to fix this so I don't have to reset the z coordinate every time. Player starting at (0,0,0) in world position Player starts at (0,0,0) in world position.

Player moving to (2,0,-10)

Moving the player 2 hexs to the right should result in (2,0,0) but instead returns (2,0,-10)

Here is the code for player movement:

var screenPos = Input.mousePosition;
var worldPos = Camera.main.ScreenToWorldPoint(screenPos);
var coordinate = grid.WorldToCell(worldPos);
Debug.Log(coordinate);
//resetting the z coord
transform.position = grid.CellToWorld(coordinate);
Vector3 position = transform.position;
position.z = 0;
transform.position = position;
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

The docs for ScrenToWorldPoint say:

Screenspace is defined in pixels. The bottom-left of the screen is (0,0); the right-top is (pixelWidth,pixelHeight). The z position is in world units from the camera.

When you don't provide a z component, it defaults to 0 — zero units in front of the camera.

The camera in Unity is, by default, placed at -10 on the z axis. So that's likely where your -10 is coming from.

If you say coordinate.z = grid.transform.position.z before converting to cell coordinates, that should eliminate the unwanted offset by clamping your input to the plane of the grid.


The above works for an orthographic camera looking straight at the tilemap, which seems to be what you're using. To make this answer useful for other folks who may find it, here's how you'd handle other camera arrangements:

If you're using a perspective camera, you'll want to instead set the proper depth before unprojecting, like so:

Camera cam = Camera.main;
Vector3 screenPos = Input.mousePosition;
screenPos.z = Vector3.Dot(grid.transform.position - cam.transform.position, cam.transform.forward);
var worldPos = cam.ScreenToWorldPoint(screenPos);

If the camera is looking at the tilemap diagonally/obliquely rather than straight-on, then you'd instead use ScreenPointToRay then intersect the ray with the tilemap plane to find the world space position, since the correct unprojection depth varies across the screen.

\$\endgroup\$

You must log in to answer this question.

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