Autotiling of textures for Scenes Collection Tileset

Godot Version



I am trying to assign some logic via scripts to tiles in a TileMap, like for example tiles that have multiple lives or tiles that reappear after a certain time. Given that such dynamic behavior cannot be done with custom data layers as far as I understand (fixed & same for all tiles), I tried to implement it using Scene Collection TileSet. It seems like there is no way to use all the nice features from the Atlas, like the autotiling. Am I missing something? If not, how would you tackle this problem in the least complicated, most consistent way?

You can’t autotile scenes collection tiles as they are independent scenes that are not aware of they being in a TileMap

For your needs you only need to keep a Dictionary with the cell coordinates as key and whatever data you want to keep for each one.


extends TileMap

var cells_health = {}

func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventMouseButton:
		if event.pressed:
			var cell = local_to_map(get_local_mouse_position())
			# If we don't have information about the cell
			if not cells_health.has(cell):
				# Try to get its TileData
				var tile_data = get_cell_tile_data(0, cell)
				if tile_data:
					# If there's a TileData, try to get the health
					var health = tile_data.get_custom_data("health")
					if health > 0:
						# if health is bigger than 0 then add it to our dictionary
						cells_health[cell] = health

			if cells_health.has(cell):
				# if we have health information then substract 1
				cells_health[cell] -= 1
				if cells_health[cell] <= 0:
					# if it's less than or equal to 0 erase it from the dictionary
					# and spawn the tile after a set amount of time

func respawn_cell(coords:Vector2i, time:float = 2) -> void:
	# Get the current source_id and atlas_coords of the given coordinate
	var source_id = get_cell_source_id(0, coords)
	var atlas_coords = get_cell_atlas_coords(0, coords)
	# erase the cell
	erase_cell(0, coords)
	# wait for the amount of time
	await get_tree().create_timer(time).timeout
	# set the cell back
	set_cell(0, coords, source_id, atlas_coords)


You can also access and modify some properties of a cell’s runtime TileData information by implementing both TileMap._use_tile_data_runtime_update() and TileMap._tile_data_runtime_update(). You’ll need to call TileMap.notify_runtime_tile_data_update() whenever you need those functions to run.


This is a very good solution for this specific problem. I will probably want a diverse set of cell/tile behaviors in the end. Using a single TileMap, this approach would mean that the TileMap script handles a lot of diverse block behavior. Alternatively, one could have multiple TileMaps for each block type, but that removes some of the advantages of having a TileMap in the first place, I think.

What I opted to do instead is to have a script in the TileMap that puts a Scene representing a block type at the position of its corresponding tile at runtime. It also couples the internal block logic for health to functions for changing or deleting the tile in the TileMap using signals. The behavior of a block can that be kept in separate block scenes. This might of course come with a performance penalty, but I am not planning on placing hundreds of tiles anyway.

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