I'm getting a path outside the navigation path

Godot Version

v4.2.1.stable.mono.official

Question

I have a navigation region on the map, from the navigation server I take the navigation path and using the code below I move the character.

Before I take path:
	var point_B = NavigationServer2D.map_get_closest_point(G.map_rid, get_global_mouse_position())
	NavigationServer2D.map_get_path(G.map_rid, global_position, point_B, true)
then:
func _physics_process(delta):
	if !pathing:
		our_path = []
		%animation_player.stop()
		set_physics_process(false)
		return
	next_point = our_path[path_index] - global_position
	if next_point.length_squared() > 10.0:
		rotate_to_direction(our_path[path_index], delta)
		global_position += (next_point.normalized() * delta) * (actpoints_max * 45)
	else:
		if path_index < (our_path.size() - 1):
			path_index += 1
			_physics_process(delta)
		else:
			pathing = false

The problem is that my character can sometimes move outside the navigation grid, if I click on an area without a grid, sooner or later he will go there, and sometimes with one click.
What could be the problem?

Debug visuals!

Visualize your point_B and the raw path returned by map_get_path() and you will soon see what your agent is doing wrong when it does not follow this path point to point, line to line.

The navigation system can not give you any path point outside a navigation mesh surface. It is technically impossible to leave the navigation mesh when you move directly in a line from one path point to the next path point.

If the visualized path is wrong your navigation mesh setup is the problem. Commonly caused in 2D by creating overlap that makes the wrong navigation mesh edges connect.

If the path is correct but your actor does not move correct the bug is nearly always in the movement code or due to phyiscs engine collision setups. Try disabling physics, if the bugs go away when physics is disabled it is likely pushing your actor in wrong directions so check your collision setup. If not double check your movement code. E.g. a too high path point margin that skips way to early to the next path point index will make your actor cut all kinds of corners leaving the navigation mesh.

Video Youtube

# Script on character
func move_to(f_tpoint:Vector2 here I give mouse global position):
	safe_point = NavigationServer2D.map_get_closest_point(G.map_rid, f_tpoint)
	our_path = NavigationServer2D.map_get_path(G.map_rid, global_position, safe_point , true)
	pathing = true

func _physics_process(delta):
	if !pathing:
		our_path = []
		item_to_take = null
		%animation_player.stop()
		set_physics_process(false)
#		if in_battle: G.show_path.hide()
		return
	next_point = our_path[path_index] - global_position
	if next_point.length_squared() > 10.0:
		rotate_to_direction(our_path[path_index], delta)
		global_position += (next_point.normalized() * delta) * (actpoints_max * 45)
	else:
		if path_index < (our_path.size() - 1):
			path_index += 1
			_physics_process(delta)
		else:
			pathing = false

2024-02-11_151954

Code and video, scripts are shortened and trimmed.

The issue is the path logic loop that increases the index. The agent basically skips over all the path points in those situations right to the last path point and moves through lava. Try to highlight the path points to make it more visible. You could use a NavigationAgent2D as well for the debug that adds path points.

On a sidenote you are (re)calling the same physics override function multiple times in a frame. That is really not something that you should do as it invites problems with the physics engine. Move your pathfinding logic to its own function if you need to loop it for reasons.

1 Like

I made the move a separate function and that seems to have fixed the problem, thanks.

func _physics_process(delta):
	moving(delta)
func moving(f_delta):
        ...