Weird TileMapLayer bug

Godot Version

v4.4.1.stable.mono.arch_linux

Question

I have been using this setup to get tile coordinates from under the mouse cursor:

14		var mouse_global_pos = get_global_mouse_position()
15		var mouse_local_pos = self.to_local(mouse_global_pos)
16		cell_coords = self.local_to_map(mouse_local_pos)
17
18           #This is just for testing
19		print(astar_grid.get_id_path(old_path, cell_coords))
20		for i in astar_grid.get_id_path(old_path, cell_coords):
21			self.erase_cell(i)

But now every time i would run it these errors would occur.

level.gd:16 @ _process(): Condition "tile_set.is_null()" is true. Returning: Vector2i()
level.gd:20 @ _process(): Can't get id path. Point (17, 9) out of bounds [P: (0, 0), S: (0, 0)].
level.gd:21 @ _process(): Can't get id path. Point (17, 9) out of bounds [P: (0, 0), S: 

Its really weird because there is a dedicated tileset tres file connected to the tilemap, and if i print the tileset it outputs the correct id. But this error does not seem to impede the functionality as it still returns the correct cell coordinates and erases all cells returned by astar.

Edit: While the simple astar script works despite the errors, calling this function in an actual character movement script breaks it completely.

You don’t need to use self. here.

I’m assuming the code you’re showing is from level.gd and it’s extending TileMapLayer?

You should be able to call to_local(mouse_global_pos) directly, as well as local_to_map().

I presume local_to_map(mouse_local_pos) is complaining about tile_set being null because it means the tile size is therefore unknown, so it doesn’t know how to convert from local coords into map tile coords.

Is the tileset ever set? If so, is something removing or attempting to replace it?

You are right, self was not needed there. Tried creating a new tileset with different image, but the error is the same.

I think the question is why the tileset is null. If you can figure that out…

At this point im completely stomped, this node (TileMapLayer) is the only one that interacts with a tileset directly and it never calls anything that would edit the tileset in any way… Alright, solving such problems at 1 am is not a great idea, im going to come back to it tomorrow.

Fair.

Are you creating the tileset in code, or in the inspector panel?

Exclusively through the inspector. I created a new tilemaplayer, set it to 32x32, and created new tileset, also added custom bool data “solid” to it . In the tileset menu i imported a png with a few 32x32 tiles, then i painted “solid” = true on the walls for astar pathfinding. The weird part is that it worked perfectly without errors before.

Update: I tried creating a new tilemap node (not tilemaplayer) and put the exact same code there except added layer numeration to functions, and it worked perfectly. Seems that the issue is with using the tilemaplayer node in the first place. Sticking with a deprecated node is not a good solution so im not marking it as one.

Update2: Ok, i’ve found the problem. This error only happens when i go to Project settings > Globals > Autoload and add a global variable for the tilemaplayer script, i was using it to get data from the tilemap to other parts of the script. No idea why it does not work and even less idea on how to replace it.

Found a decent workaround, instead of having all functions inside the TileMapLayer node i created a child node for it. Then instead of creating global variable for TileMapLayer script i created one for its child node’s script. In the child node script i created a variable for the TileMapLayer reference and wrote all functions here.

extends Node2D

@onready var level = $/root/Main/Level
@onready var astar_grid = level.astar_grid


func mouse_coords() -> Vector2i:
	return level.local_to_map(to_local(get_global_mouse_position()))
	
func self_coords(self_ref) -> Vector2i:
	return level.local_to_map(to_local(self_ref.position))

Now works like a charm.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.