godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
86.31k stars 19.21k forks source link

Changing property cell_size has no effect on pathfinding in AStarGrid2D #89089

Open ichthyoidoc opened 4 months ago

ichthyoidoc commented 4 months ago

Tested versions

System information

Godot v4.2.1.stable - macOS 13.6.2 - Vulkan (Forward+) - integrated Apple M1 Max - Apple M1 Max (10 Threads)

Issue description

Using AStarGrid to find a path through tiles based on a tilemap, changing cell_size to anything above or below the tile size of the tilemap has no effect on where the pathfinding ends up.

The expected outcome (unless I'm misunderstanding the point of "cell_size") is that the tilemap can be divided further than the initial tile size to gain more precise movement for pathfinding. Instead, no matter what you change the cell_size to, objects will always land in a 16x16 grid (or whatever the tilemap tile size is)

Steps to reproduce

Relevant code:

extends TileMap

var astar = AStarGrid2D.new() var map_rect = Rect2i()

func _ready() -> void: var tile_size = get_tileset().tile_size var tilemap_size = get_used_rect().end - get_used_rect().position map_rect = Rect2i(Vector2i(), tilemap_size)

astar.region = map_rect
astar.cell_size = Vector2(16,16)

astar.default_compute_heuristic = AStarGrid2D.HEURISTIC_EUCLIDEAN
astar.default_estimate_heuristic = AStarGrid2D.HEURISTIC_EUCLIDEAN
astar.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_ONLY_IF_NO_OBSTACLES
astar.update()

for i in tilemap_size.x:
    for j in tilemap_size.y:
        var coordinates = Vector2i(i, j)
        var tile_data = get_cell_tile_data(0, coordinates)
        if tile_data and tile_data.get_custom_data('name') == 'wall':
            astar.set_point_solid(coordinates)

Changing the Vector2 in "astar.cell_size = Vector2(16,16)" above to any other Vector2 has virtually no effect on pathfinding.

Minimal reproduction project (MRP)

AStarGrid_01.zip

ichthyoidoc commented 4 months ago

Actually, I should also note that commenting out the "astar.cell_size = Vector2(16,16)" line completely also has absolutely no effect on pathfinding or where the object ends up.

If this isn't a bug, then is seems that the cell_size property has no function at all?

dalexeev commented 4 months ago

cell_size and offset are needed for get_point_path(), not for get_id_path() and other methods. This is simply a multiplier and an offset of the result id path. See the demo.

ichthyoidoc commented 4 months ago

Thanks, the demo definitely helped me understand a bit, though I still don't exactly understand the real differences between get_point_path and get_id_path, except that get_id_path seems safer to use?

Is there a way to actually set cell sizes in a way that divides tiles appropriately? In other words, let's say my tilemap has tiles sizes of 16x16, but when using AStarGrid for pathfinding, I want to divide each of those tiles further so that four 4x4 cells fit inside those 16x16 tiles? And in this way, get a more specific point for an object to go to within said tile of the tilemap?

^This is basically what I thought cell_size did.

dalexeev commented 4 months ago

No, these properties only affect the get_point_path() result. For all other calculations, you must use cell IDs (integer coordinates that do not take into account cell size and offset). In conjunction with TileMap, you may be interested in the local_to_map() and map_to_local() methods. You can also use the integer division and remainder operations.