Is it possible to get tilemap tiles that has higher y-sort that certain position?

Godot Version

godot-4.2

Question


I wanted to make the tiles on specific layer with higher y-position than player position semi-transparent.
I was thinking of using TileMap.get_used_cells(int layer) to retrieve all the cells and compare it with player y position.

But, it feels like I am checking y-position twice*, since tilemap y-sort is enabled, it would be already checking the position.

My question is. Is there some way to tap into tilemap y-sorting checking code, and just add my little logic to it so that I don’t have to check it twice.

1 Like

As far as I know, y-sorting happens at the end before drawing the whole scene and gathering all the drawing information. TileMap is not doing any internal y-sort. So, try doing what you have in mind. Good luck!

1 Like

oh I see. Thank you!

oopsy my poopsy. I just realized that you cannot modulate individual tile. dang.

You can change the cell modulate by implementing TileMap._use_tile_data_runtime_update() and TileMap._tile_data_runtime_update()

For example:

extends TileMap

var cells_alpha = {}

func _tile_data_runtime_update(layer: int, coords: Vector2i, tile_data: TileData) -> void:
	tile_data.modulate.a = cells_alpha.get(coords, 1.0)


func _use_tile_data_runtime_update(layer: int, coords: Vector2i) -> bool:
	return cells_alpha.has(coords)


func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventMouseButton:
		if event.pressed:
			var cell = local_to_map(get_local_mouse_position())
			cells_alpha[cell] = cells_alpha.get(cell, 1.0) - 0.2
			notify_runtime_tile_data_update()

Result:

1 Like

holy jesus! I didn’t know that thank again.
let me try it

works great!

extends TileMap

@export var player: Player
var wall_layer = 1
var player_coords: Vector2i
var cells_alpha = {}
func _tile_data_runtime_update(layer, coords, tile_data):
	tile_data.modulate.a = cells_alpha.get(coords, 1.0)
	
#Warning: Make sure this function only return true when needed. 
#Any tile processed at runtime without a need for it will imply a significant performance penalty.
func _use_tile_data_runtime_update(layer, coords):
	return cells_alpha.has(coords)

func _process(delta):
	player_coords = local_to_map(player.global_position)
	var coords = get_used_cells(wall_layer)
	for coord in coords:
		print("coord:{0}, player:{1}".format([coord.y, player_coords.y]))
		if coord.y >= player_coords.y:
			cells_alpha[coord] = 0.3
		else:
			cells_alpha[coord] = 1.0
		notify_runtime_tile_data_update(wall_layer)

Running the code in process worry me a bit but its good to know that this is possible. Thank you

How would you use a tween on the alpha value of the tile?

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