How do I make a spread effect that will stop at collision?

Godot Version

Any

Question

This is what I have in mind:

Basically, an area that always expand on all front, unless it’s already filled or it reaches some static collision, it keeps going.
It’s ultimately just for a visual effect so not having functionality is fine, as long as it renders.
Any idea how this can be achieved? Thanks.

Hi !

Will this effect be redundant? (Several uses, with different collision shapes, etc…)

Or will it be a one-time effect?

What do you mean by that?
If it’s one-time, wouldn’t that still require me to do some procedural work, which should allow me to apply the same thing to other use cases?

I just realized Hexagon might be the key to my problem.
It expands on all front, only has 6 directions to check each update; using TileMap, it should be pretty easy to mark where the obstacle lays.
That should work? Probably?

something like this.
but if you want to utilize the physicsbody, then there will be another solution

someone try to do it with shader, but it looks like only in a box, i dont think it can bounce back or into small gaps like your picture shown

this problem also looks like path finding algorithm (example the Dijkstra’s path finding Algorithm) looks alike but not




Probably not the most efficient way but should be enough for my need.

extends TileMap

var check_next_update: Array[Vector2i]
var occupied_cells: Array[Vector2i]

func _ready() -> void:
	occupied_cells = get_used_cells(0)
	check_next_update = get_used_cells(1)

func update() -> void:
	var _check_next_update: Array[Vector2i] = check_next_update.duplicate()
	
	for cell: Vector2i in check_next_update:
		for surrounded_cell: Vector2i in get_surrounding_cells(cell):
			if !occupied_cells.has(surrounded_cell):
				set_cell(1, surrounded_cell, 1, Vector2i(0, 0))
				occupied_cells.append(surrounded_cell)
				_check_next_update.append(surrounded_cell)
		_check_next_update.erase(cell)
	
	check_next_update = _check_next_update.duplicate()

func _input(event: InputEvent) -> void:
	if event.is_action_pressed("ui_accept"):
		update()