2d-extras
2d-extras copied to clipboard
Axial coordinates with hex-based tilemap
I recently began experimenting with the hexagonal tilemap that was added to unity. I noticed that, by default, the hexagonal grid system uses offset coordinates, as described here: https://www.redblobgames.com/grids/hexagons/#coordinates-offset
Is there any way to modify the tilemap so that it instead uses axial coordinates, as described here: https://www.redblobgames.com/grids/hexagons/#coordinates-axial ?
Thank you in advance for any help you can provide
Hi, unfortunately you will not be able to directly use axial coordinates on the Grid API for Hexagonal Grids.
However, I'll try to add a C# extension script for GridLayouts using Hexagonal Cell Layout which does the conversion internally, for example:
- OffsetToAxial/AxialToOffset
- AxialToLocal/LocalToAxial
Is that something that will be useful to you or do you need something more? Thanks!
Hi ChuanXin. I think a C# extension would be a good idea. While I waited for a response, I added a couple of extension methods to the TileMap component in my own project. Now I have access to SetTileAxial, GetTileAxial, etc...
I've been finding it to work quite well. I can make a Pull Request with my methods over the weekend if you'd like.
Yes, please do! This would be very helpful! Thank you!
Hi, @NickMakesGames, any news on this? I've been trying to find a solution for hours, so I'd really like to see how you solved this.
you might want to check out Catlikecoding's amazing tutorial on Hex game programming... he deals with this issue there. https://catlikecoding.com/unity/tutorials/hex-map/part-1/
I'm interested in the same but to convert to cube coordinates. Cube has pretty straightforward ways of getting ranges of hex tiles and doing line of sight which would be really useful. I looked at Catlike coding but it's all pre native tilemaps.
Here is solution how to convert coordinates from Unity Cell (GridLayout.WorldToCell) to Cube and backwards:
private List<Vector3Int> GetNeighbors(Vector3Int unityCell, int range)
{
var centerCubePos = UnityCellToCube(unityCell);
var result = new List<Vector3Int>();
int min = -range, max = range;
for (int x = min; x <= max; x++)
{
for (int y = min; y <= max; y++)
{
var z = -x - y;
if (z < min || z > max)
{
continue;
}
var cubePosOffset = new Vector3Int(x, y, z);
result.Add(CubeToUnityCell(centerCubePos + cubePosOffset));
}
}
return result;
}
private Vector3Int UnityCellToCube(Vector3Int cell)
{
var yCell = cell.x;
var xCell = cell.y;
var x = yCell - (xCell - (xCell & 1)) / 2;
var z = xCell;
var y = -x - z;
return new Vector3Int(x, y, z);
}
private Vector3Int CubeToUnityCell(Vector3Int cube)
{
var x = cube.x;
var z = cube.z;
var col = x + (z - (z & 1)) / 2;
var row = z;
return new Vector3Int(col, row, 0);
}