godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.12k stars 20.2k forks source link

Navigation2D.get_simple_path() marked as deprecated but does not execute on 3.5.2 #76368

Closed Vivraan closed 1 year ago

Vivraan commented 1 year ago

Godot version

3.5.2

System information

Windows 11

Issue description

In version 3.5.2 in my case, Navigation2D.get_simple_path() is not working as expected -- it doesn't generate a valid array.

As a corollary, can a guide be created for migrating legacy Navigation[23]D code to code which uses Navigation Servers?

Steps to reproduce

  1. Run the linked project.
  2. Check if the debugger stops at guard.gd:36.

Minimal reproduction project

Download/clone my gamedev.tv Heist Meisters project copy from here.

The relevant code is present in res://scenes/characters/guard.gd.

Edit

The example code works perfectly in 3.4.5.

smix8 commented 1 year ago

The issue is properly that you query your navigation path in a _ready() function.

On the first frame when the SceneTree does the setup for all nodes the navigation map is empty cause all navigation related nodes just started sending their navmesh data to the server.

The NavigationServer syncs on the next physics frame so if you use get_simple_path() to early you are querying an empty navigation map which returns an empty path array.

You can remove the Navigation2D node and replace the old Navigation2D.get_simple_path() code with Navigation2DServer.map_get_path(get_world_2d().navigation_map, start_position, target_position, false).

Vivraan commented 1 year ago

One more related question would be about managing multiple tileset layers which were previously under the Navigation2D node -- how should those be used?

smix8 commented 1 year ago

The navigation_layers for the navigation mesh are part of the NavigationPolygonInstance.

The 5th parameter of Navigation2DServer.map_get_path() is to filter the navigation layers in the path search.

Mind you that 2D navigation polygons are not stack able. They can not overlap or stack on top of each other in the same place on the same navigation map.

Vivraan commented 1 year ago

So is the recourse going to be to make a complex polygon which avoids obstacles? Or is there a way to mark obstacles? The earlier Node based approach abstracted away a lot of these considerations effectively.

smix8 commented 1 year ago

I don't think I can fully follow what you mean. There are no "obstacles" in pathfinding context. There is either a navigation mesh / polygon or there is not.

The old node did nothing special except creating a new navigation map for all its child nodes. You can still do that by using Navigation2DServer.map_create() and then place all your regions or agents on that new map.

If you delete the Navigation2D node all the regions and agents will just join the default navigation map of the World2D.

smix8 commented 1 year ago

I think this discussion can be closed. Feel free to comment if there is something still unresolved.