All Questions

Community

M
Gabriel Matusevich

Block path using TileMap

Hello! I also want to block the unit from moving if there is a particular Tile that should block path like a Wall tile... However even if I set the tile with a collision shape I don't see a method in the TileSet class to know if any particular tile has a collision shape.
I can always do it by the name of the tile (i.e.: if it contains the word "wall" in the tile name) but I would like to know if there is a way to get the collision information on any given tile, so far I didn't find that in the docs.

  • M
    Gabriel Matusevich replied

    I'm solving it "manually" like this:

    func is_occupied(cell: Vector2) -> bool:
    var map_cell := _map.get_cellv(cell)
    var tile_name := _map.tile_set.tile_get_name(map_cell)
    if map_cell == TileMap.INVALID_CELL or is_wall_tile(tile_name):
    return true
    return true if _units.has(cell) else false

    func is_wall_tile(tile_name: String):
    return tile_name.begins_with("wall")
  • M
    Gabriel Matusevich replied

    I tried using

    tile_get_shapes(cell)

    But returns an `[]` empty array

  • M
    Gabriel Matusevich replied

    Nevermind, It just worked, my Collision shape was not been applied properly, I'd still like to know if you have some recommendations for detecting blocker/wall tiles

  • Nathan Lovato replied

    Your solution seems good. I would do it differently, not checking if every tile is a wall one by one, but rather writing down which tile ID or IDs are walls and using TileMap.get_used_cells_by_id() to get an array of all wall tiles and integrate them in the AStar's obstacles.

    The idea is you may only have a handful of tile types that are obstacles, so you can write a function that outputs an array of all obstacles in the game. Imagine that you have a board with the floor, a path, houses, and mountains, created in that order in your tileset. The floor has the ID 0, the path 1, houses and mountains 2 and 3 respectively.

    You'll need Godot 3.2.4 to use the code below, as previous version don't have the method Array.append_array(). But here's how you can write a function that outputs an array of all obstacles, in this example, houses and mountains.

    extends TileMap

    const OBSTACLE_IDS = [2, 3]

    func get_all_obstacles(ids := []) -> Array:
    var obstacles := []
    for id in ids:
    obstacles.append_array(get_used_cells_by_id(id))
    return obstacles