AStarGrid2D not detecting TileMap custom data

Godot Version

Godot-4.2.2

Question

Hi,

I’ve been stuck with getting AI movement to work correctly. So far, this is what I have for my script, based on this video: https://www.youtube.com/watch?v=qJKBT3KOLiY

extends CharacterBody2D

@onready var player = $"../Player"
@onready var tile_map = $"../TileMap"
@onready var sprite_2d = $Sprite2D

var speed = 16
var astar_grid: AStarGrid2D
var is_moving: bool

func _ready():
	astar_grid = AStarGrid2D.new()
	astar_grid.region = tile_map.get_used_rect()
	astar_grid.cell_size = Vector2(16, 16)
	astar_grid.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_NEVER
	astar_grid.update()
	
	var region_size = astar_grid.region.size
	var region_position = astar_grid.region.position
	
	for x in region_size.x:
		for y in region_size.y:
			var tile_position = Vector2i(
				x + region_position.x,
				y + region_position.y
			)
			
			var tile_data = tile_map.get_cell_tile_data(0, tile_position)
			
			# this is not detecting the "wall" custom data
			if tile_data != null:
				if tile_data.get_custom_data("wall"):
					astar_grid.set_point_solid(tile_position)

func _process(_delta):
	if is_moving:
		return
	
	move()

func move():
	var path = astar_grid.get_id_path(
		tile_map.local_to_map(global_position),
		tile_map.local_to_map(player.global_position)
	)
	
	path.pop_front()
	
	if path.size() == 1:
		print("arrived at target")
		return
	
	if path.is_empty():
		print("can't find path")
		return
	
	var original_position = Vector2(global_position)
	global_position = tile_map.map_to_local(path[0])
	sprite_2d.global_position = original_position
	
	is_moving = true

func _physics_process(_delta):
	if is_moving:
		sprite_2d.global_position = sprite_2d.global_position.move_toward(global_position, 1)
		
		if sprite_2d.global_position != global_position:
			return
		
		is_moving = false

In my TileMap I have custom data, and part of this custom data includes “wall” at Layer 0.


image
image
Essentially, it should be detecting the walls in the image but the tile data generated by get_cell_tile_data() is returning a null list and so my AI doesn’t realize there are walls there. It can still follow the player but when the player moves behind the wall it loses visibility when based on this code I don’t think it should.

Any help would be greatly appreciated. Thanks!

It looks correct however personally id throw a print string after the if wall check to see if it’s even taking that branch. Perhaps you’ve already done that but its where I’d start.

OK it looks like it is in fact finding the walls, I think it was due to the way my map was set up and how TileMap works, the coordinates of TileMap only take into account the area that is painted over.

The only thing left now is to figure out the enemy sprite’s position, it is currently in between tiles. So far I’ve tried moving the sprite and collision area but that hasn’t worked successfully yet. Any thoughts?

image

position.snapped()?

something like position = position.snapped(Vector2.ONE * tile_size)

OK I figured it out. What I ended up doing was changing the offset of the sprite itself, so that way I don’t need to use position.snapped()

When I tried using position.snapped() it ended up causing the pathfinding to be wonky, so this solution ended up working for me. Thanks for the help!