0 votes

Hi,

I'm working on a 2D Zelda-like game. The map is procedurally generated.

  for x in range(chunk_size):
     for y in range (chunk_size):
        var a = terrain_noise.get_noise_2d(x+x_pos,y+y_pos)
          if a > snow_height:
           terrain_tile = SNOW
        elif a > mountain_height:
           terrain_tile = MOUNTAIN_DARK
        elif a > lower_mountain_height:
           terrain_tile = MOUNTAIN_LIGHT
        elif a > grass_height:
           terrain_tile = GRASS[randi()%GRASS.size()]
        elif a > sea_level:
           terrain_tile = SAND
        elif a > deep_sea_level:
           terrain_tile = SHALLOW_WATER
        else:
           terrain_tile = DEEP_WATER
        $Navigation2D/TerrainMap.set_cell(x+x_pos,y+y_pos,terrain_tile)

        spawn_guard(x_pos,y_pos)

All tiles in the tileset have a square navigation poligon of the exact tile size.

After the map is generated, some NPC should spawn a get to move around:

func spawn_guard(x_pos,y_pos):
   yield(get_tree().create_timer(1.0), "timeout")
   var spawn = guard.instance()
   var posi = Vector2(get_parent().get_node("World/Navigation2D/TerrainMap").map_to_world(Vector2(x_pos+20,y_pos+20)))
   spawn.position = posi
   var goal = Vector2(get_parent().get_node("World/Navigation2D/TerrainMap").map_to_world(Globales.player_pos))
   spawn.goal = goal 
   var path = $Navigation2D.get_simple_path(posi,goal)
   spawn.path = path
   add_child(spawn)

My problem is:
when yield is called at the beginning of the spawn_guard function to have a pause between map generation and spawning, everything works fine.
When I remove the yield line, the variable path is empty.

It looks like the map is not yet "finally built" (navigation poligons connected?), so getsimplepath returns an empty array.

How can I make sure, the tilemap is completed, so getsimplepath has all navigation poligons to get to work?

asked May 27 in Engine by Rochambeau (17 points)

1 Answer

0 votes
Best answer

the world state (the one needed for the simplepath to work) is not updated, it will be updated at the end of the frame, but you are calling the spawguard in the same frame.

the solution is to forcefully update the nav_polygon by turning it on and off again, but it's not that easy for a tilemap

https://godotengine.org/qa/26104/how-can-you-get-navigation2d-recognize-updates-the-nav-mesh

(i had the same problem 2 years ago, but i cant remember if I solved more efficiently than simply yield 1 frame, i'll dig a little in my past project too see if i discover anything)

answered May 27 by Andrea (520 points)
selected May 28 by Rochambeau
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.