I just started using Navigation nodes and have the following setup:
Navigation region in main scene:

NavigationAgent2D that is represented by an enemy scene:

NavigationObstacle2D, in this case a wall:

And the code in script attached to enemy AI child node:

func actor_setup():
	await get_tree().physics_frame
func _ready():
	call_deferred("actor_setup")
	set_state(State.PATROL)
	navigation_agent.path_desired_distance = 4.0
	navigation_agent.target_desired_distance = 4.0
	navigation_agent.avoidance_enabled = true

func _physics_process(delta):
if navigation_agent.is_navigation_finished():
		maneuver_location_reached = true
	else:
		var next_move_position = navigation_agent.get_next_path_position() - actor.global_position
		actor_velocity = next_move_position.normalized() * movement_speed
		actor.velocity = actor_velocity
	actor.move_and_slide()

The end result is that enemy NavigationAgent2D does not take wall cover into consideration and goes around it. Instead it keeps trying to reach navigation target position. You can see on screenshot that the path is intersected by a yellow wall, so it should go around it (the enemy is the small green sprite stuck to the yellow wall...ignore the red raycast pointing left....):

What am I missing? Why is the obstacles not taken into consideration when navigation_agent is getting its next path point?

  • SOLVED

    Found a solution myself - as it seems, NavigationObstacle2D nodes work correctly. However, after scouring GitHub issues related to my problem, I learned that path taken by NavigationAgent2D does not change when NavigationAgent2D is about to hit a NavigationObstacle2D. What changes in this case is the velocity of the agent. In other words, the path of agent stays the same, but the velocity is changed according to obstacles it encounters and this velocity "pushes" the agent away from the obstacle, thus making the agent avoid the obstacle by going around it.

    I also learned that using this approach is not recommended (probably because of resource strain that obstacles present), but my game does not have static obstacles and walls around which I can draw a NavigationRegion. I plan to use procedural generation of levels, so NavigationObstacle2D is currently my best option.

    This is how I modified the code:

    In _readyfunction I connected to "velocity_computed" signal that is emitted by agent:
    navigation_agent.connect("velocity_computed", Callable(self, "move_actor"))

    At the end of _physics_process function I get the next path position of agent. This path position * movement speed of agent gives me a velocity that I set in agent:
    if not navigation_agent.is_navigation_finished():
    var next_move_position = navigation_agent.get_next_path_position() - actor.global_position
    actor_velocity = next_move_position * movement_speed
    navigation_agent.velocity = actor_velocity

    I then added the function that I connected before to "velocity_computed". I named this function "move_actor" that receives the computed velocity from agent and then apply this velocity to my enemy. I also reduce the velocity with (movement_speed / 15) because if I use .normalized() on the received velocity vector, the enemy goes around the obstacle too slow:
    func move_actor(velocity :Vector2):
    if not navigation_agent.is_navigation_finished():
    actor_velocity = velocity
    actor.velocity = actor_velocity / (movement_speed / 15)
    actor.move_and_slide()

    So to sum up, path taken by NavigationAgent2D is not affected by NavigationObstacle2D. Instead, NavigationAgent2D can calculate the velocity needed to avoid the NavigationObstacle2D and this make the agent go around obstacles.

SOLVED

Found a solution myself - as it seems, NavigationObstacle2D nodes work correctly. However, after scouring GitHub issues related to my problem, I learned that path taken by NavigationAgent2D does not change when NavigationAgent2D is about to hit a NavigationObstacle2D. What changes in this case is the velocity of the agent. In other words, the path of agent stays the same, but the velocity is changed according to obstacles it encounters and this velocity "pushes" the agent away from the obstacle, thus making the agent avoid the obstacle by going around it.

I also learned that using this approach is not recommended (probably because of resource strain that obstacles present), but my game does not have static obstacles and walls around which I can draw a NavigationRegion. I plan to use procedural generation of levels, so NavigationObstacle2D is currently my best option.

This is how I modified the code:

In _readyfunction I connected to "velocity_computed" signal that is emitted by agent:
navigation_agent.connect("velocity_computed", Callable(self, "move_actor"))

At the end of _physics_process function I get the next path position of agent. This path position * movement speed of agent gives me a velocity that I set in agent:
if not navigation_agent.is_navigation_finished():
var next_move_position = navigation_agent.get_next_path_position() - actor.global_position
actor_velocity = next_move_position * movement_speed
navigation_agent.velocity = actor_velocity

I then added the function that I connected before to "velocity_computed". I named this function "move_actor" that receives the computed velocity from agent and then apply this velocity to my enemy. I also reduce the velocity with (movement_speed / 15) because if I use .normalized() on the received velocity vector, the enemy goes around the obstacle too slow:
func move_actor(velocity :Vector2):
if not navigation_agent.is_navigation_finished():
actor_velocity = velocity
actor.velocity = actor_velocity / (movement_speed / 15)
actor.move_and_slide()

So to sum up, path taken by NavigationAgent2D is not affected by NavigationObstacle2D. Instead, NavigationAgent2D can calculate the velocity needed to avoid the NavigationObstacle2D and this make the agent go around obstacles.

    spolmy changed the title to [SOLVED] NavigationObstacle ignored by NavigationAgent .
    a month later

    spolmy
    Can you please help me. I try to use the same way to use the obstacles but my navigation agent moves through forward the obstacle and gets trapped inside it. I tried various values for avoidance parameters but it is always stuck inside or before the obstacle

    Marked "Best Answer" as it seems to be solved. 👍