I am getting familiar with the Godot, getting some basic work done and everything has been rather nice and easy to get behind, but I've stumbled onto a problem I can't seem to fix.
Trying to build a rogue-like dungeon, I've been following a tutorial to create a FOV effect. It's very simple - loop through every single tile, raycast to check if player can see it. Slight adjustments for the direction, but that's not the point.
The issue that I'm having is that the collisions occurs all over the place... For example, on this picture I cast ray from player (cyan heart) to every tile (green dot), but don't get collision on the walls (even though they have colliders):
Here, I'm getting collisions everywhere, but there is nothing to collide with, floor tiles have no colliders:
Finally, here I'm getting something similar to the result I'm looking for, but some walls are still ignored and not collided with, while others work just fine:
I have no clue what it is... There shouldn't be any colliders in the scene apart from generated ones in the tilemap (walls and doors). I've checked, and the positions for raycasting are selected rather precisely, so the problem is the collision.
Why is it like this? What can I do to avoid it?
Here's the code for visual's update and FOV calculation (and highlighting raycast points + collisions):
for entity in game_map.entities:
entity.position = Vector2(entity.grid_x * game_map.TILE_SIZE, entity.grid_y * game_map.TILE_SIZE)
for n in $test.get_children():
var player_center = tile_to_pixel_center(player.grid_x, player.grid_y)
$"test-heart".position = player_center
var space_state = get_world_2d().direct_space_state
for x in range(game_map.level_size.x):
for y in range(game_map.level_size.y):
var sprite_cell = Sprite.new()
var x_dir = 1 if x < player.grid_x else -1
var y_dir = 1 if y < player.grid_y else -1
var test_point = tile_to_pixel_center(x,y) + (Vector2(x_dir,y_dir) * (game_map.TILE_SIZE / 2))
sprite_cell.position = test_point
sprite_cell.texture = load("res://assets/sprites/test-dot.png")
var occlusion = space_state.intersect_ray(player_center, test_point)
if !occlusion || (occlusion.position - test_point).length() < 1:
game_map.visibility_map.set_cell(x, y, -1)
game_map.visibility_map.set_cell(x, y, 0)
var sprite = Sprite.new()
sprite.texture = load("res://assets/sprites/test-cross.png")
sprite.position = occlusion.position
I'm really are a bit of a noob with the engine, although have done similar things before, but if I'm missing something obvious - like a setting or two, please, let me know! Or if it's something more complex - I would also love to find out.