I’m using AStar2D with a TileMap and I’m trying to draw a line that represents the path of the unit from its current position to where the mouse was clicked.
The problem I’m facing is that the path doesn’t appear after the first click. The navigation itself works perfectly but I have to press the mouse a second time in order for the path to show and after that it works fine.
Here is the part of the script relatable:
func _input(event):
if event.is_action_pressed("move") == false:
return
var id_path
if is_moving:
# Then add a new path starting from the tile the unit moving to
id_path = astar_grid.get_id_path(
tile_map.local_to_map(target_position),
tile_map.local_to_map(get_global_mouse_position())
)
else:
# If not moving, then add a path normally
id_path = astar_grid.get_id_path(
tile_map.local_to_map(global_position),
tile_map.local_to_map(get_global_mouse_position())
).slice(1)
if id_path.is_empty() == false:
current_id_path = id_path
# This is a PackedVector2Array that I'm feeding to the Path.gd
current_point_path = astar_grid.get_point_path(
tile_map.local_to_map(target_position),
tile_map.local_to_map(get_global_mouse_position())
)
Path.gd:
extends Node2D
@onready var unit= $"../Unit"
func _process(delta):
queue_redraw()
func _draw():
if enemy.current_point_path.is_empty():
return
draw_polyline(enemy.current_point_path, Color.DARK_BLUE, 10)
Here is the rest of the Unit script:
@export var speed := 3
@export var tile_map: TileMap
var astar_grid: AStarGrid2D
var current_id_path: Array[Vector2i]
var current_point_path: PackedVector2Array
var target_position: Vector2
var is_moving: bool
# Called when the node enters the scene tree for the first time.
func _ready():
astar_grid = AStarGrid2D.new()
astar_grid.region = tile_map.get_used_rect()
astar_grid.cell_size = Vector2(128, 128)
astar_grid.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_NEVER
astar_grid.offset = Vector2(64, 64)
astar_grid.update()
for x in tile_map.get_used_rect().size.x:
for y in tile_map.get_used_rect().size.y:
var tile_position = Vector2i(
x + tile_map.get_used_rect().position.x,
y + tile_map.get_used_rect().position.y
)
var tile_data = tile_map.get_cell_tile_data(0, tile_position)
if tile_data == null or tile_data.get_custom_data("walkable") == false:
astar_grid.set_point_solid(tile_position)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta):
if current_id_path.is_empty():
return
if is_moving == false:
target_position = tile_map.map_to_local(current_id_path.front())
is_moving = true
global_position = global_position.move_toward(target_position, speed)
if global_position == target_position:
current_id_path.pop_front()
current_point_path.remove_at(0)
if current_id_path.is_empty() == false:
target_position = tile_map.map_to_local(current_id_path.front())
else:
is_moving = false
current_point_path.clear()