+1 vote

Hi, I was wondering how to use the navigation agent. (Godot 4.0 alpha 7)

settargetlocation ( Vector2 location ) is how the target location is done. But how is starting location handled.

getnavpath ( ) keeps giving me an empty array.

I have a tile map with navigation and collision.

The documentation is not being very helpful here. It says:-
The agent needs navigation data to work correctly. NavigationAgent2D is physics safe.
navigation data means what. I thought the tile map with navigation tiles counted as navigation data.

Godot version 4.0
in Engine by (202 points)

1 Answer

+2 votes
Best answer

The starting position is the agent's parent position. Also get_nav_path is empty because it is computed asynchronously. Wait for the path_changed signal, after which get_nav_path() should give a valid result.

I built a minimum example to test this. My hierarchy looks like this:

  • nav_test (Node2D)

    • tile_map (TileMap)
    • player (Sprite2D)

      • agent (NavigationAgent2D)
    • goal (Position2D)

And the script attached to nav_test:

extends Node2D

@onready var agent: NavigationAgent2D = $player/agent
@onready var goal: Position2D = $goal
@onready var player = $player


func _ready() -> void:
    agent.velocity_computed.connect(on_velocity_computed)
    agent.path_changed.connect(on_path_changed)
    agent.target_reached.connect(on_target_reached)
    agent.set_target_location(goal.global_position)


func _physics_process(delta: float) -> void:
    var next_location = agent.get_next_location()
    var v = (next_location - player.global_position).normalized()
    agent.set_velocity(v)


func on_velocity_computed(safe_velocity: Vector2) -> void:
    player.position += safe_velocity


func on_path_changed() -> void:
    print(agent.get_nav_path())


func on_target_reached() -> void:
    print("reached goal")
    get_tree().quit()
by (278 points)
selected by

Thank you! I will test it out. And let you know.

And btw how is collision avoidance handled with navigation agent? It says automatic but right now it gets stuck in walls.

You need to define where it's safe for an agent to travel. You can do this by adding NavigationRegion2D nodes and drawing paths, or by using a TileMap with navigation shapes defined on the tiles.

In either case you draw the paths where there is open floor, though be sure to leave a large enough gap between the walls and floor to account for the agent's size.

Thank you again!
I am going to work with the answer you gave to my other question.
Dynamic obstacle avoidance is what I would like to do. Avoid NPCs that are not the target.

To make a dynamic obstacle you would add a NavigationObstacle2D node as a child to an object (npc, moving hazard, etc).

As long as you use the "safe" velocity from thevelocity_computed signal everything should work as expected.

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 Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.