![]() |
Attention | Topic was automatically imported from the old Question2Answer platform. |
![]() |
Asked By | BarbosNikitos |
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):
func update_visuals():
for entity in game_map.entities:
entity.position = Vector2(entity.grid_x * game_map.TILE_SIZE, entity.grid_y * game_map.TILE_SIZE)
call_deferred("recalc_fov")
func recalc_fov():
for n in $test.get_children():
$test.remove_child(n)
n.queue_free()
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)
else:
game_map.visibility_map.set_cell(x, y, 0)
if (occlusion):
var sprite = Sprite.new()
sprite.texture = load("res://assets/sprites/test-cross.png")
sprite.position = occlusion.position
$test.add_child(sprite)
$test.add_child(sprite_cell)
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.
Just in case, this is definitely not extra colliders, I’ve found and turned on the Visible collision shapes, here’s the result:
BarbosNikitos | 2020-01-17 10:07
The problem might be outside of this code. Make sure you haven’t swapped X and Y or wrote twice X or twice Y.
Zylann | 2020-01-17 13:38
But that’s the thing, I don’t see how the problem can occur outside of this code. Only position handling is not included, but all the positions highlighted with green dots are actual positions in the scene, it clearly knows what the player center and test points are for space_state.intersect_ray(player_center, test_point) - that’s why I highlighted them with these gizmos, to check that the places are detected correctly.
It’s the check that happens that just appears very weird…
BarbosNikitos | 2020-01-17 18:00
What is the code of tile_to_pixel_center
? Did you check if it could be a problem about local vs global, child vs parent relative positions? Raycasts expect world space positions.
Zylann | 2020-01-17 19:40