I'm trying to figure out how to properly calculate a cursor's location relative to a rotated Tilemap
. First, a couple pictures to illustrate the problem.
Camera rotation: 0
Tilemap rotation: 0
Everything looks good and works great, except we're wanting the tiles to have a psuedo-3d perspective, which means rotating them along the x axis:
Camera Rotation: 0
Tilemap rotation: 60
This gets us our perspective, however besides a narrow band of tiles near the middle, the calculation for finding the tile stops working:
So far I've tried two different approaches that both net the same result:
var touchPosition = getScreenPosition();
var worldPosition = Camera.main.ScreenToWorldPoint(touchPosition);
worldPosition.z = 0;
var cellPosition = tilemap.WorldToCell(position);
Notably I'm having to do some z-axis manipulation to account for the camera position which I suspect could be part of my initial problem. Instead I swapped over to doing raycasts to find my intersection:
var plane = new Plane(Vector3.back, Vector3.zero);
var touchPosition = getScreenPosition();
var ray = Camera.main.ScreenPointToRay(new Vector3(touchPosition.x, touchPosition.y, 0f));
if (plane.Raycast(ray, out float hit))
{
var point = ray.GetPoint(hit);
var cellPosition = tilemap.WorldToCell(point);
}
That eliminated the need to adjust the z-axis, however with the Tilemap
rotated I still fail to find the correct Tile
. Interestingly, if I also rotate the Camera
itself, everything goes back to working again without the perspective and being offset (since the camera's physical location hasn't changed).
Camera rotation: 60
Tilemap rotation: 60
My suspicion is that despite the raycast finding a valid hit, WorldToCell()
isn't taking the transform's rotation into account when doing its conversion. I couldn't find the source for that particular function so if that's available somewhere I'll happily start there. Besides that, if someone can help point me to the math I might need to do in order to get this calculation correct, that'd be wonderful.
Many thanks!
Turns out the answer to this was incredibly simple: https://gamedev.stackexchange.com/a/5220 had the info I needed, specifically the sentence:
Here is the traditional version with horizontal hexes that are effectively squished in the vertical axis to make a pseudo-isometric look.
Instead of rotating the Tilemap
60 degrees, I simply set its Y-scale to 0.5
and voila, everything worked perfectly.