Hex Tilesets in Godot 4.0
For this example, I am using a pack of hexagon tiles from the amazing Kenney.
Configuring a tileset to work with hexes
When creating a new tileset, under the Tile Shape menu, there’s now a “Hexagon” option.
Configuring the tilemap
We are going to use two layers with our tilemap for this demo. Simply scoll down to the layers section of the Inspector for the tilemap and click “Add Element”. I have named mine for clarity.
Configuring the Tile Atlas
For our tileset texture, we need to configure our atlas to have a separation of x:2px, y:2px. Then, simply select the texture and let Godot import all the tiles for you!
Interacting with the TileMap from code
Highlighting a ring around a selected hex
The code is pretty simple;
- Clear the layer
- Convert the cursor’s screen coordinates to the map coordinates
- Loop through a list of neighbour cells and set each cell to a tile from the Tile Atlas
func _input(event):
if event is InputEventMouseButton:
if (event as InputEventMouseButton).button_index == MOUSE_BUTTON_LEFT:
tilemap.clear_layer(1)
var map_mouse_pos = tilemap.local_to_map(get_global_mouse_position())
for neighbour in tilemap.get_surrounding_cells(map_mouse_pos):
tilemap.set_cell(1, neighbour, 0, Vector2i(6,2))
![](images/ring-around-hex.gif)
Highlighting an arc around a point (such as a player)
The code here is a little more complicated.
- Clear the layer
- Convert the cursor’s screen coordinates to the map coordinates
- Check that the distance from the point on the map is equal to 1
- Get a list of neighbours and for each neighbour, if the distance between it and the mouse position is equal to 1, set the cell to a tile from the Tile Atlas
# Artfully ripped from here: https://stackoverflow.com/a/18394812
func hex_distance(start:Vector2, dest:Vector2) -> int:
var distance = max(max(abs(dest.y-start.y),
abs(ceil(dest.y / -2) + dest.x - ceil(start.y / -2) - start.x)),
abs(-dest.y - ceil(dest.y / -2) - dest.x + start.y + ceil(start.y / -2) + start.x))
return distance
func _input(event):
if event is InputEventMouseButton:
if (event as InputEventMouseButton).button_index == MOUSE_BUTTON_LEFT:
tilemap.clear_layer(1)
var map_mouse_pos = tilemap.local_to_map(get_global_mouse_position())
if hex_distance(map_mouse_pos, arc_origin) == 1:
var dir = Vector2(map_mouse_pos - arc_origin)
var mouse_arc = tilemap.get_surrounding_cells(map_mouse_pos)
tilemap.set_cell(1, map_mouse_pos, 0, Vector2i(6,2))
for point in mouse_arc:
if hex_distance(Vector2(point), arc_origin) == 1:
tilemap.set_cell(1, Vector2(point), 0, Vector2i(6,2))
![](images/arc-around-point.gif)