How do i check for and change individual tiles outside of an area2d in a process function?

Godot Version

v4.6.1.stable.mono.official [14d19694e]

Question

This is a follow-up from this post, but the main gimmick of what I’m making is that the light that comes from a prism thingy shows hidden objects, hence enabling and disabling their collisions as well.

ezgif-112681702ee33013

In the gif, I have a tilesetlayer with two 4x4 tiles with separate physics layers solely for collisions whereas I can use another tilesetlayer for the visual tiles. By using an area2d within the prism light, I use the body_shape_entered and exited signals to change the collision tilesetlayer tiles individually like this:

func _on_entered(body_rid : RID, body: Node2D, _body_shape_index : int, _local_shape_index: int):
    if body is TileMapLayer:
        #print("entered " + body.name)
        var tile_pos = body.get_coords_for_body_rid(body_rid)
        var tile_data = body.get_cell_tile_data(tile_pos)
        
        if tile_data:
            #print("found tile!")
            if body.get_cell_atlas_coords(Vector2i(6,4)): 
                body.set_cell(tile_pos, 0, Vector2i(1, 0), 0) #tile with physics layer 0 that collides with player
            pass
    pass

func _on_exited(body_rid : RID, body: Node2D, _body_shape_index : int, _local_shape_index: int):
    if body is TileMapLayer:
        #print("left " + body.name)
        var tile_pos = body.get_coords_for_body_rid(body_rid)
        var tile_data = body.get_cell_tile_data(tile_pos) 
        
        if tile_data:
            #print("left tile!")
            if body.get_cell_atlas_coords(Vector2i(1,0)):
                body.set_cell(tile_pos, 0, Vector2i(6, 4), 0) #tile with physics layer 1 that doesn't collide with player
            pass
    pass

The problem I’m stumped on now is whenever I move the light too quickly, the _on_exited function sometimes doesn’t work, resulting in tiles left behind that still collide with the player, which is also shown in the video.
I had an idea of using another function that checks for the tiles outside of the area2d with maybe an array that lists all of the tiles that have been enabled so it can disable them once the area2d stops covering them, but that would probably need to be placed in a process function which doesn’t have the arguments I would also need for finding the separate tiles again.
What could I do?

While I’m at it, I might as well mention another problem I’m having. Interestingly enough, whenever _on_entered is signaled, I get this error each time, is there any fix to this as well?

Is the light meant to be moving so fast in the game?

(post deleted by author)

Yes, it’s controlled by the mouse. I’ve tried slowing down the speed it follows the mouse at considerably as well, yet there are still ways to make the light move fast enough to leave behind the lasting colliding tiles. Though, any slower and it’d feel pretty sluggish.

In that case you’ll have to get all cells that are in light’s radius and check the intersection status of each individually. Pretty much as I described in your previous thread.

Could you show me how you would do that? I’m probably overthinking it like crazy right now.

Would it work better if the player’s layer changed instead of the environments? Functionally the player has to also be outside of the light to pass through, could you do something like this? Assuming the tiles have a collision layer of 2.

func _on_body_entered(body: Node2D) -> void:
    if body is Player:
        body.set_collision_layer_value(2, true)

func _on_body_exited(body: Node2D) -> void:
    if body is Player:
        body.set_collision_layer_value(2, false)

If so you could apply any other visual effect pixel perfect through shaders

Yeah I might just use this instead, I was initially planning some kind of feature to launch the player with hidden tiles, but I should probably look into that when I’m more familiar with the engine. Thank you!!!

How would that work if the player is so large compared to tiles?

I’m not exactly sure but if I revert back to swapping out the tiles, it lets me do this

ezgif-1f58e84c7bb17e66

I’m assuming if I add momentum, it’d launch the player which would open up some fun possibilities I think