Godot 3.5 2D Navigation Tutorial
Published: 2022-09-15 18:58:25

Learn the new Navigation system in Godot 3.5 by creating a city map with cars and pedestrians navigating the streets and sidewalks! Here's a quick video of what we'll have by the end of this tutorial.

<iframe width="560" height="315" src="https://www.youtube.com/embed/Zej8wi7VQ-s" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## Introduction
[Godot 3.5 is out](https://godotengine.org/article/godot-3-5-cant-stop-wont-stop), and it's awesome. Perhaps the biggest feature for 2D games is the reworked navigation system, which has been ported over from the upcoming 4.0 release. Among the benefits of the new system are a unified navigation server which removed the need for dedicated `Navigation2D` nodes and the introduction of the `NavigationAgent2D`, which abstracts and simplifies tedious navigation tasks such as pathfinding and collision avoidance. 

In this tutorial, we will construct the city of `GodotTown` using free assets from the incomparable [Kenney](https://www.kenney.nl/). Within our city we will have roads and sidewalks, with cars and pedestrians navigating on them. We'll implement pathfinding with and without using `NavigationAgent2D` so that we can compare the pros and cons. 

The first few sections will be about designing and building the level, and will mostly deal with `TileMaps`. If you already know this stuff and just want to see the new navigation features, skip down to [Adding Navigation for Cars](#Adding-Navigation-for-Cars).

By end of this guide, we hope you have a better understanding of 2D Navigation in Godot 3.5, and that you're inspired to make some awesome games using it!

Here are the prerequisites: 
* Download [Godot 3.5](https://godotengine.org/download/linux)
* [Clone](https://git-scm.com/doc)/Download [this project from Github](https://github.com/CSMA-Technology/godot-town)
    * This repo starts as an empty 2D Godot scene, with nothing but the assets we are going to use inside of an `assets` folder
    * Each branch within the repo corresponds with the start of a section in this tutorial (starting with `step-1/creating-the-tilemap`). We will have instructions below for skipping steps. If you know nothing about Git and this branch thing sounds weird to you, don't worry! Just download the project and follow along, you don't have to touch any of that. 

Let's get started!

## Step 1: Creating the Tilemap
In this section, we will be creating the foundation of our game using two [TileSets](https://docs.godotengine.org/en/stable/classes/class_tileset.html), that we will use in [TileMaps](https://docs.godotengine.org/en/stable/classes/class_tilemap.html) for Roads and Sidewalks to build the cityscape of our level. It will look like this:
![the final TileMaps](https://i.imgur.com/Pvo4fJs.png)


> **TLDR**: Add two `TileMaps` to the Main Scene (one for roads and one for sidewalks), and create `TileSets` using `tilemap_packed.png`.
> If you want to skip this section and move on to [Adding Cars and Pedestrians](#step-2-adding-cars-and-pedestrians), run this command `git checkout step-2/adding-cars-and-pedestrians`.

A `TileMap` is a grid of tiles used to quickly and easily paint a game's layout or background. `TileMaps` have a lot of useful features which make them super powerful to use when building the map of your game: 

- You can quickly place a large amount of different types of tiles within the viewport
- You can auto-arrange and add a level of randomness to the tiles to make it look more natural (e.g. different planks across a wooden floor) using [AutoTiles](https://docs.godotengine.org/en/stable/tutorials/2d/using_tilemaps.html#autotiles)
- You can add collision, occlusion, and most importantly for this tutorial, navigation to each tile

`TileMaps` have `TileSets`, which are resources that hold all the properties of the tiles.

> **Note**: This is not a `TileMap` tutorial, so we won't really be going into too much detail about them. If you're not familiar with them, just go through the motions and follow our instructions exactly, and you can focus on Navigation. (Alternatively, scroll back up to the TLDR and follow the instructions to skip to the next section.) 
> Check out the official Godot Tutorial on [Using TileMaps](https://docs.godotengine.org/en/stable/tutorials/2d/using_tilemaps.html#autotiles) for more info.

> If you'd like us to create a tutorial on `TileMaps` (or any other topics), please let us know by commenting below!

First, add two `TileMap` nodes to the Main Scene, naming one `Roads` and the other `Sidewalks`. Technically, we could draw the map with one `TileMap`, but separate `TileMaps` are necessary here for the Navigation we want to achieve. More on this in the coming sections!

![two TileMap nodes in our scene](https://i.imgur.com/SpboprZ.png)

Now we'll create the `TileSets` for each of the `TileMaps`, first for the Roads. Click on the `Roads` node in the scene tree, then in the **Inspector** find the `Tile Set` property, which should be empty. 

In the dropdown, select **New TileSet**, then click on the `TileSet` and the **TileSet Editor** should pop up at the bottom (where the console and debugger are located). It's easiest to deal with `TileSets` in a larger view, so we'll expand the menu by clicking on this button at the bottom of the right hand hand corner of the editor: ![the "Expand Bottom Panel" button](https://i.imgur.com/zwvw2JY.png)

Next, find `tilemap_packed.png` in the `assets` folder and drag it to the left panel of the **TileSet Editor**. 

<iframe width="560" height="315" src="https://www.youtube.com/embed/Pxxdtgjx688" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Now create a single tile by clicking **New Single Tile**.

To make sure our selections are accurate, we want grid snapping. To turn it on, click on the **Snap To Grid** button ![Snap to Grid button](https://i.imgur.com/J8Qw17o.png)

Make any selection by clicking anywhere on the tileset. The menu should then open in the right panel. Find the properties under **Snap Options** and set `Step` to `x: 16 y:16`. Now we can easily select the upper left-hand corner of the first road tile (towards the bottom left of the spritesheet), which has a crosswalk print on it.

<iframe width="560" height="315" src="https://www.youtube.com/embed/01ZRChuFUXo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

We can continue to create single tiles for the rest of the road; however, instead we're going to create an [Atlas](https://docs.godotengine.org/en/stable/tutorials/2d/using_tilemaps.html#atlas-tiles), which allows us to create multiple tiles at once by selecting a rectangular region of the spritesheet. 

Select **New Atlas** at the top and drag across all the road tiles in the bottom left of the spritesheet. Once done, expand **Selected Tile** in the **Inspector**, and we should see `Tile Mode` set to `ATLAS_TILE` and `Subtile Size` set to `x:16 y:16`. Change the `Name` of the atlas, so we can see it clearly in the `TileMap` menu later on.

<iframe width="560" height="315" src="https://www.youtube.com/embed/5WhWk4gGN3A" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Once that's done, we can go back to the **2D Scene Editor** and click on the `Roads` node again. 

Before drawing our map, set the `cell_size` to match our `step` in the `TileSet`. In the **Inspector**, under **Cell** set the `Size` to `x: 16 y: 16`.

<img alt="the cell size in the inspector" src="https://i.imgur.com/EYRLBvv.png" width=283 height=409 />

Now we can draw our road by clicking on the `roads` atlas from the Tilemap menu, and then selecting the tiles we want to paint. 

<iframe width="560" height="315" src="https://www.youtube.com/embed/ATDPlC2_FvE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Repeat the process for `Sidewalks`. We actually used [AutoTiles](https://docs.godotengine.org/en/stable/tutorials/2d/using_tilemaps.html#autotiles) for our Sidewalks, but another atlas will work as well! After creating the `TileSet`, draw the sidewalks as well -- optionally, you can add more `TileMaps` for buildings and decorations to liven up your town. 

Now we should have a full map like below!

> Note: if you notice a faint gray line in between tiles on your finished map, you may need to re-import your spritesheet. By default, Godot uses "filter" mode to import the files, but you can turn it off. Click on `tilemap_packed.png` and go to the **Import** tab at the top of the left-hand panel. Find the `Filter` property and make sure it is unchecked, then click **Reimport**, and those ugly gray lines should disappear!

![the finished TileMaps](https://i.imgur.com/yAuyNmz.jpg)

Awesome, now we have our map! In the next section, we'll be adding cars and people to the level and scripting them to move around the town.

## Step 2: Adding Cars and Pedestrians
Now that we have some roads and sidewalks, we can add cars and pedestrians, each trying to get somewhere. 

> **TLDR:** Create two scenes with `KinematicBody2D` as the root node, and name one `Car` and the other `Pedestrian`. Assign them a sprite from the assets folder and a collision shape, then make a script that they will both share that moves them towards a goal. 
> To skip to the next section and move on to [Adding Navigation for Cars](#step-3-adding-navigation-for-cars), run this command `git checkout step-3/adding-navigation-for-cars`.

Cars and pedestrians will work in basically the same way:
* They will be assigned a goal, which is a `Node2D`
* They will move towards that goal at a designated `speed`
* They will `queue_free` when they hit the goal

We'll be using a [`KinematicBody2D`](https://docs.godotengine.org/en/stable/classes/class_kinematicbody2d.html#class-kinematicbody2d) node for both of these, which is a very important node for 2D games! If you're not familiar with it, make sure to check out [this tutorial](https://docs.godotengine.org/en/stable/tutorials/physics/kinematic_character_2d.html). 

For our first draft, cars and pedestrians will ignore any navigation and just move in a straight line towards the goal, disappearing when they get there. 

Let's start by creating our `Car` scene. Create a new child in our main scene, a `KinematicBody2D` node, and then configuring it in-place and saving the branch as a scene. This is an alternative to creating a new empty scene, and it has the advantage of allowing us to visualize our car on the scene it will ultimately be in.

Rename the `KinematicBody2D` to `Car`. Then create a child `Sprite` node, and assign that `Sprite` `tilemap_packed.png` as its texture. Don't worry, Godot's `Sprite` nodes have a handy way to crop the texture, and we're going to use that to get just the portion of the image that has a car. 

In the **Inspector** for the `Sprite` node, expand the **Region** section, enable it, and set the `Rect` values to: `x: 240 y: 230 w: 32 h: 32`

![a yellow car](https://i.imgur.com/PTwmhXA.png)


And there we have our car! Move the car to somewhere on the roads, and make sure you are moving the `Car` node and not just the sprite! 

Now just add a `CollisionShape2D` as a child of the `Car` node, give it a new `RectangleShape2D` from the `Shape` property in the **Inspector**, and set the `Extents` to `x: 10 y: 10`. 

Before we get to the script, let's make goals for the cars and pedestrians to move towards. Create two new `Node2D`s at the top level of the main scene, and rename them to `CarGoal` and `PedestrianGoal`. Drag them to nice spots on the road and sidewalks, respectively.

![example locations of the goals](https://i.imgur.com/4uaVhx6.png)


As a little bonus, we're going to use a new feature introduced in Godot 3.5, [Scene Unique Names](https://docs.godotengine.org/en/stable/tutorials/scripting/scene_unique_nodes.html)! Just right-click on our two goal nodes and tick the box that says **% Access as Scene Unique Name**:
![The Scene Unique Name option](https://docs.godotengine.org/en/stable/_images/unique_name.png)

This is going to enable us to refer to the goals in our code by their name, instead of by their relative location in the scene. 

Now add a script to the `Car` node and call it `Movable.gd`. Let's start by exporting some variables that we know we'll need:
```GDScript
export (String) var goal # Our scene unique name
export var current_speed = 50 # The speed we should move at (pixels per second)
export var arrival_tolerance = 10 # How close to a point do we get before we are there
```

Let's pause and explain `arrival_tolerance`. When we eventually implement pathfinding, our cars will get an array of points to follow in sequence. Our script is then going to say:
>Try to get to point **X**. If we are within `arrival_tolerance` of point **X**, we can consider ourselves there and move on to the next one. 

Without this, we would need to perfectly line up our center point at each position along the path, which may not always be possible (for example, if there is a collision preventing us from getting exactly there). 

We have our `goal` export variable as a string, which will be a scene unique name. We need to find the position of that node when we start up. So let's add the following [`onready`](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html) variable right under the `goal` declaration:

`onready var goal_pos = get_node(goal).global_position`

Next, we'll write a simple movement function using [move_and_collide](https://docs.godotengine.org/en/stable/classes/class_kinematicbody2d.html#class-kinematicbody2d-method-move-and-collide), which we will run at every physics frame:
```GDScript
func move_towards_goal(speed):
    # Get a unit-length vector pointing in the direction we want to go
    var direction = (goal_pos - global_position).normalized()
    # Apply our speed to the direction vector to get our movement vector
    var movement = direction * speed
    # Move our KinematicBody2D node
    move_and_collide(movement)
```

And *finally*, call our movement function within `_physics_process`. We are using this lifecycle method instead of `_process`, because `_physics_process` runs at consistent intervals, making movement smooth and independent of framerate. 

```GDScript
func _physics_process(delta):
    # When we reach our goal (within tolerance), queue_free
    if global_position.distance_to(goal_pos) <= arrival_tolerance:
        queue_free()
    # If we are not at our goal, keep moving!
    else:
        move_towards_goal(delta * current_speed)
```

One note about the above script: `delta` is the time (in seconds) since the last time `_physics_process` was called (i.e., since the last "Physics Frame"). However, since `_physics_process` runs at fixed intervals, it should always be the same. Even so, multiplying by that value gives us the desired behavior of `speed` being expressed in pixels per second.

And there we have it, our `Car` is complete, and our script (sans comments) should be looking like this:
```GDScript
extends KinematicBody2D

export (String) var goal
onready var goal_pos = get_node(goal).global_position
export var current_speed = 50
export var arrival_tolerance = 10

func _physics_process(delta):
    if global_position.distance_to(goal_pos) <= arrival_tolerance:
        queue_free()
    else:
        move_towards_goal(delta * current_speed)


func move_towards_goal(speed):
    var direction = (goal_pos - global_position).normalized()
    var movement = direction * speed

    move_and_collide(movement)
```

Before saving the car as a scene, let's add a value for the `Goal` property. Click the `Car` and then type in the scene unique name of our goal (`%CarGoal`) into the **Inspector** field, including the percentage sign.

<img alt="the Goal name in the inspector" src="https://i.imgur.com/E4UzRdi.png"  width="303" height="245" />


Next, right-click on the `Car` node and select **Save Branch as Scene**. If you run the scene here, the car should move towards the goal!

Adding pedestrians will follow the exact same process, and it should be a snap. 

First, add a `KinematicBody2D` to the main scene, and rename it to `Pedestrian`. Add a `Sprite` to it, and give it the same `tilemap_packed.png` texture. This time, here are the magic numbers for the `Region` property:
`x: 384 y: 0 w: 16 h: 16`

![a dude](https://i.imgur.com/COw37Sv.png)


Give the `Pedestrian` a `CollisionShape2D`. We can select a `RectangleShape2D` again, and give it the following extents: `x: 5 y: 8`.

Now we can just grab our `Movable.gd` script from the **FileSystem** section and drag it onto the `Pedestrian`. Before we save to a scene, assign a value to the `Goal` export value in the **Inspector**; this time it should be `%PedestrianGoal`. Save our dude as a scene by right-clicking and selecting **Save Branch as Scene**. 

Before we run the scene, let's add a little organization so we can add a bunch of cars and pedestrians. Make two new `Nodes` in the scene, and name them `Cars` and `People`. Drag the `Car` node into `Cars` and the `Pedestrian` node into... well, you get it. 

Now just click on the `Car` and/or `Pedestrian` and hit **Ctrl + D** to duplicate them as many time as you want. You can drag them around to different positions on the map, and modulate their colors (**Inspector** -> **CanvasItem** -> **Visibility** -> `Modulate` ) to add some diversity to GodotTown! You can also turn the visibility of the `CollisionShape2D` off (in the `Pedestrian` and/or `Car` scene) to see the colors more easily. 

![A hidden CollisionShape2D](https://i.imgur.com/EmUmPMr.png)

![GodotTown with some residents](https://i.imgur.com/kZDoFQ4.png)


Now let's run the scene and see what happens...

<iframe width="560" height="315" src="https://www.youtube.com/embed/OsF5zyKEuK0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

We can see that cars are driving all over the sidewalk (and in the void of space!), the pedestrians are jaywalking, everyone is crashing into each other, it's madness! In the next step, we are going to add navigation and use navigation layers to make sure pedestrians only walk on the sidewalks and cars only drive on roads. 

## Step 3: Adding Navigation for Cars
> **TLDR:** Add navigation polygons to our road tiles, and then change the `Movable.gd` script to make a path with `Navigation2DServer`.
> To skip to the next section and move on to [Adding Navigation for Pedestrians](#step-4-adding-navigation-for-pedestrians), run this command `git checkout step-4/adding-navigation-for-pedestrians`.

Now we will add navigation to our `Roads` `TileMap`! We will define a region on each of the tiles we use that Godot will consider navigable, and when those regions match up along the edge, they will be merged into one larger navigable area. This will allow the `NavigationServer2D` to plot a path between any two points on the contiguous region. 

First, let's click on our `Roads` `TileMap`, open the **Tileset Editor** from the **Inspector**, and expand it. With a left click on a road tile, or by clicking the left/right arrows on the top of the editor, select the `Roads` atlas we defined earlier. You'll know you have the right one when you see the correct `Name` property under **Selected Tile** in the **Inspector**. 

<img alt="the tile setting int he inspector" src="https://i.imgur.com/dbK2vA6.png"  width="296" height="471" />


Click on **Navigation** from the top of the Tileset Editor, and then click **New Rectangle** from the row underneath, or hit **Shift + R**. Click into the tile you had selected and you'll see it light up in a light green color; that is a navigation region! 

<iframe width="560" height="315" src="https://www.youtube.com/embed/I7YErBlvU-A" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Note that what we just did marked the **entire** tile as navigable. We could just mark specific parts within the tile as navigable instead by turning off snapping (not recommended) or changing the values of `Snap Options -> Step` in the **Inspector**. This would allow us to do something like excluding the edges of tiles from navigation, which would be useful because the path that is ultimately drawn will be for the *center* of the car, which means if it runs along the edge, the car will be halfway off the road. We do want to keep our cars off the edge, but we will do so in a simpler way: by only marking the tiles we use for the middle of the road as navigable. 

After clicking through the tiles and assigning navigation regions to the middle tiles, we are left with this:

![our selected tiles](https://i.imgur.com/p3cxdGx.png)


A note and a warning:
* **Note**: Our specific spritesheet/tiles makes this process very easy because we are marking entire tiles as navigable, but in future projects we can use either the **Rectangle** (`Shift + R`) or **Polygon** (`Shift + P`) tool to draw the navigation on only a portion of each tile. (**Note:** we actually did ) The Rectangle Tool works by clicking-and-dragging a rectangle, and the Polygoon Tool works by clicking on points that will be vertices of the polygon. In both cases, it is helpful to enable grid snapping ![Snap to Grid Button](https://i.imgur.com/J8Qw17o.png) and adjust the `Step` in the **Inspector** under `Snap Options`.
* **Warning**: When using the **Polygon Tool** for navigation, the first point we click on will **not** show up as a red dot. It is not until the second point is clicked that both points display. If we double-click the same first point because we thought there was no vertex there, it will create two overlapping points, which will cause errors down the road. 

Before we proceed, let's run the game and see our changes. In order to view the navigation region we will need to do two things: 
1. Click on the `Roads` `TileMap` node and in the **Inspector** select **Navigation -> Bake Navigation**. This is required for navigation to work, but is off by default because not all `TileMap` nodes will have navigation regions.
2. In the top menu of Godot, select **Debug -> Visible Navigation**. This will highlight navigation regions in a light transparent green when we run the game. 

Now when we run the game, we will see the highlighted navigation regions, which should form a coherent, drivable space for our cars. Of course, we haven't changed their script yet, so the behavior of the cars and people will be unchanged. 

![the map with navigation](https://i.imgur.com/lT0wZ50.png)

Now, let's put that navigation to good use. First, let's assign some `Navigation Layers` to the two navigable `TileMaps`. These layers will enable us to separate adjacent navigable regions (the roads and the sidewalks), so that cars will only use one, and pedestrians will only use the other. On each `TileMap`, expand the **Navigation** section in the **Inspector**, and ensure that `Navigation Layers` is set to `1` for `Roads`, and `2` for `Sidewalks`.

Then we can crack open `Movable.gd` and add the following export variable:
`export (int, LAYERS_2D_NAVIGATION) var nav_layer = 1`

This will allow us to keep sharing the same script between cars and pedestrians, while telling them they can only traverse specific `Navigation Layers`. The `LAYERS_2D_NAVIGATION` constant is a [special export flag](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_exports.html?highlight=bit%20flag#exporting-bit-flags) which will make the variable show up as a bit flag selector in the **Inspector**. 

<img src="https://i.imgur.com/bhmwYhG.png"  width="295" height="313" />


Just like collisions in Godot, it is important to remember that these values are not "normal" ints, but rather, [bit flags](https://www.hendrik-erz.de/post/bitwise-flags-are-beautiful-and-heres-why). Since we will be working with just `1` and `2` exclusively, this won't affect us much, but if we were to add, say, a cyclist who could traverse both navigation layers, then he would have both layers `1` and `2` enabled, and that would be expressed in code as an integer with a value of `3`. 

Now *finally* we will get to the good part. We will modify our script to use the new [`Navigation2DServer`](https://docs.godotengine.org/en/stable/classes/class_navigation2dserver.html?highlight=Navigation2dserver) to create a path for the cars along the roads, and then follow it. And that can be done with just a few lines of code!

First, add two new variables to the top of `Movable.gd`: 
`var path = null` and `var path_idx = 0` that we'll use in our new solution.

And then modify `move_towards_goal`:
```GDScript!
func move_towards_goal(speed):
    # If the path is null or empty, create it and return. 
    if not path:
        # map_get_path returns an array of points, ending at the goal if it is reachable
        path = Navigation2DServer.map_get_path(get_world_2d().navigation_map, global_position, goal_pos, false, nav_layer)
        # This will point to our next target along the path
        path_idx = 0
        return
    # We are using the same tolerance as before to determine if we have arrived at an intermediate point along the path
    while global_position.distance_to(path[path_idx]) <= arrival_tolerance:
        path_idx += 1
    # Same logic as before, but this time going to the next point in the path instead of the goal
    var direction = (path[path_idx] - global_position).normalized()
    var movement = direction * speed
    move_and_collide(movement)
```

Let's call some stuff out from that code snippet.
* This function will be called every physics frame, but the navigation will not be baked and ready until the second physics frame. That is why we `return` from the `move_towards_goal` function after generating the path, and if the path is an empty array, it will generate again next time (because an empty array is falsy in GDScript).  
* The key function we are using is [`Navigation2DServer.map_get_path`](https://docs.godotengine.org/en/stable/classes/class_navigation2dserver.html?highlight=Navigation2dserver#class-navigation2dserver-method-map-get-path). If you are familiar with the old (Godot <= 3.4) navigation system, this is the replacement of [`Navigation2D.get_simple_path`](https://docs.godotengine.org/en/stable/classes/class_navigation2d.html?highlight=get_simple_path#class-navigation2d-method-get-simple-path). You'll notice two new parameters though, `map` and `navigation_layers`. The `Navigation2DServer` serves as a single object responsible for all navigation, so in order to accomodate for more complex navigation scenarios, Godot 3.5 introduces `maps`, which contain navigation `regions`. 
    * We won't be defining additional maps in this guide, but that would be one way to, for instance, have overlapping navigation regions that do not interact. Instead, we get the default navigation map with `get_world_2d().navigation_map`.
    * We will be using the `navigation_layers` parameter, though, which informs the `Navigation2DServer` which layers in the given map should be considered for this path. As you can see above, we will be defining different layers for the roads and sidewalks. 
* We want our cars to move along the path, which means we want them to move to one point at a time along the array returned by `map_get_path`. Instead of modifying this array, we are using a pointer (`path_idx`) to choose the next spot to move towards, and we are advancing that pointer when we have "arrived" according to our tolerance. 

That's it! Before we test it, open the `Car` scene and make sure the `Nav Layer` property is set to `1` in the **Inspector**. Do the same for the `Pedestrian` scene, setting it to `2`. Since we have not added the second `Navigation Layer` for the `Sidewalks` yet, we'd expect the pedestrians to stay still now. Let's run it and find out.

<iframe width="560" height="315" src="https://www.youtube.com/embed/K_OcHwMzPNs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

> **Note:** When you run the game at this point, you may see the below error within the debugger --
> ![get_relative_transform_to_parent errors](https://i.imgur.com/LtWHwRp.png)
> The navigation should still work as expected with the above instructions, so right now you can ignore this error (though it's annoying). This is a known issue in Godot 3.5 and is being fixed in an [upcoming patch](https://godotengine.org/article/release-candidate-godot-3-5-1-rc-1).


Looking good! Let's make those people walk now. 

## Step 4: Adding Navigation for Pedestrians
Now the cars are in motion! But as you can see, when we play the scene the people are still standing in place. Let's go through how to fix that. 

> **TLDR:** Add navigation regions to the `Sidewalks`, and ensure that the export var `nav_layer` in the `Pedestrian` scene is set to match the `Navigation Layers` property in `Sidewalks`. In this tutorial, we are using layer 2.
> To skip to the next section and move on to [Refactoring Pedestrians to use NavigationAgent2D](#step-5-refactoring-pedestrians-to-use-navigationagent2d), run this command `git checkout step-5/refactoring-pedestrians-to-use-navigationagent2d`

First, we'll take what we learned in the previous section and add Navigation to the Sidewalk tiles. 

Again, open the `TileSet` editor by clicking on the `Sidewalks` node in the scene tree, then clicking on the `TileSet` selection and then expanding the menu from the bottom ![the "Expand Bottom Panel" button](https://i.imgur.com/zwvw2JY.png)

Click on the individual Sidewalk tiles, or select the atlas (or Autotile set if you used that) and choose the first tile. This time, we will be adding Navigation Polygons to some of the tiles rather than just plain rectangles. The act of adding polygons is a little wonky, so bear with the process.

The first block of tiles are just rectangles (but we're not including the lighter edges which are the "curbs"), so continue on like we did before for the Roads. Once those are done, select the middle group of tiles shaped like this:
<img alt="a single sidewalk tile" src="https://i.imgur.com/9ns1exv.png" width="185" height="176" />

Click on **Navigation** and then select **New Polygon**, by clicking the button ![the "New Polygon" button](https://i.imgur.com/6AlKy1b.png) 
or typing **Shift + P**.


This is where it gets a little tricky. First, you'll select a starting point in the tile for your new polygon. When we click that first point, unfortunately the UI does not show any feedback or indication of where that point is, but **make sure not to double click the point** -- otherwise, Godot will think that these are two separate points in the Navigation polygon and it may cause pathing to break during runtime. After clicking the starting point, move your mouse to the next corner or point of the shape, and continue on around the tile. Like the starting point, when you've finished the shape, **do not double click the final point**, as this again could break pathing.

<iframe width="560" height="315" src="https://www.youtube.com/embed/wDY6ahOjN0E" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

> **Note**: If after you finish this section and run the game, you see the following error: ![Polygon Tool button](https://i.imgur.com/5x6gDRr.png)
> It may be due to badly drawn navigation polygons -- it's best to delete all the navigation polygons on the affected `TileSet` and carefully re-draw them. This process should be much improved in [Godot 4](https://godotengine.org/article/tiles-editor-rework)!

Do the same for the rest of the Sidewalk tiles, so that we have the navigation areas looking like this: 
![sidewalk tiles with navigation](https://i.imgur.com/OXM88xQ.png)

Once we are done with the nav regions in this Tileset, go back to the 2D scene editor. 

Now, we just need to ensure that the nav layers match up between the `Sidewalk` tiles and the `Pedestrian` nodes.

In the properties of the `Sidewalk` tilemap, go to the **Navigation** section and ensure that only layer `2` is selected in `Navigation Layers`. Then, go to the `Pedestrian` scene (not just the node, because we want to change the property for *all* instances of `Pedestrians`) and in the **Inspector**, make sure that the `Nav Layer` property (which corresponds to the `export var nav_layer` in our `Movable.gd` script) is also set to `2`.

Awesome! Now, we should be able to run the game and see the cars **and** people moving. 

<iframe width="560" height="315" src="https://www.youtube.com/embed/7CamLFRknHA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

To make things more natural, let's change the speed on some of the pedestrians, and see what happens to the pathing. Pick a couple of the pedestrians in the middle of the map and change their `Speed` to something low, like `10`. 

Run the game again, and take note of how the people stack up behind the slower pedestrian, getting stuck and having to walk at the same slow speed all the way to the goal -- looks a little weird, right?

<iframe width="560" height="315" src="https://www.youtube.com/embed/cX-_iaYRHOY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Let's take a look at how to make this look more natural in the next section!

## Step 5: Refactoring Pedestrians to use NavigationAgent2D 
We're in the home stretch! In this last section, we will refactor the code for the `Pedestrians` to use `NavigationAgent2D`, and really see the strengths of this newly revamped navigation system in Godot 3.5. 

> **TLDR:** Add a `NavigationAgent2D` node to the `Pedestrian` scene. Detach the existing `Movable.gd` script from `Pedestrian` and create a new script that uses `NavigationAgent2D` for navigation and collision avoidance.
> To skip this section and see the final result, run this command `git checkout final-game`

Up until now, we have been using the base `Navigation2DServer` for the pedestrians walking along the sidewalk. This works pretty well for getting the characters from their starting point to the goal. But as you saw from the last tweak in the previous section where we made some of the people walk slower, collision avoidance isn't happening at all with just the `Navigation2DServer`. Ideally, we'd like the people to walk around each other if they are going different speeds, just like they would in real life.

[NavigationAgent2D](https://docs.godotengine.org/en/stable/classes/class_navigationagent2d.html) abstracts away many of the pathfinding tasks we did ourselves, and also implements its own collision avoidance system. To be clear, we could accomplish everything that the Navigation Agent does manually in our own code using `Navigation2DServer`, but we'd be writing a lot more code, and it could get messy. However, the agent is not without its complications -- here are some pros and cons.

**`NavigationAgent2D` Pros**

- Simplifies previously tedious code for pathfinding
- Easier to use for beginners in Godot Navigation
- Sufficient in most cases for simple navigable regions & obstacles
- Standardized approach to navigation that will increasingly become the norm -- especially upon the release of Godot 4.0

**`NavigationAgent2D` Cons**

- The collision avoidance has limitations, and it takes a lot of tweaking of the agent properties to get it looking smooth
- Can be hard to debug
- It's more of a black box and not as customizable as manually programming the navigation (i.e. we do not have the option to leave the path "unoptimized" as we did before). It's hard to achieve a certain look to your pathing with just the `NavigationAgent2D`, leading developers to sometimes choose a different implementation altogether.

Now that we know what `NavigationAgent2D` can do, let's see how it will bring us to our final product.

Go to the `Pedestrian` scene and add a `NavigationAgent2D` node to the scene tree. Click on this node, and in the Inspector, open the **Pathfinding** section. Make sure that in `Navigation Layers` layer `2` is selected to match the nav layer of the `Sidewalks`.

<img alt="the NavigationAgent2D in the scene tree" src="https://i.imgur.com/GPXemKE.png" width=237 height=181 />

<img alt="the navigation layers in the inspector" src="https://i.imgur.com/I4xD9VI.png" width=237 height=178 />

Since we will be writing a new script using the agent for pedestrians, remove the existing `Movable.gd` script from the `Pedestrian` scene by right clicking the root node, and selecting **Detach Script** from the menu. Now, let's attach a new script to the `Pedestrian` and call it `MovableWithAgent.md`.

We still want some of the same properties that `Cars` have, so start by copying over the following class variables from the `Movable.gd` script -- we'll need: 

- `goal`
- `goal_pos`
- `current_speed`
- `arrival_tolerance`

Next, we'll implement the basic movement using the agent with the following code.

```GDScript
extends KinematicBody2D

export (String) var goal
onready var goal_pos = get_node(goal).global_position
export var current_speed = 50
export var arrival_tolerance = 10

func _ready():
    # Tell the agent where it should navigate to
    $NavigationAgent2D.set_target_location(goal_pos)

func _physics_process(delta):
    # Similar to the car, when the pedestrian gets close enough to the goal, despawn it
    if global_position.distance_to(goal_pos) <= arrival_tolerance:
        queue_free()
    # Find the next point in the path to navigate to and update the internal path within the agent
    var next_location = $NavigationAgent2D.get_next_location()
    # Calculate the direction and movement just as before
    var direction = (next_location - global_position).normalized()
    var movement = direction * current_speed
    move_and_collide(movement * delta)
```

Let's talk about our current code.
- As soon as the `NavigationAgent2D` enters the scene tree we need to tell the agent where the `KinematicBody2D` should go by calling `set_target_location()` in the `_ready()` function.
- As the node moves, `NavigationAgent2D` keeps track of the path and what the next point is. In order to update the path, we must call `get_next_location()` in every physics frame -- hence calling it in `_physics_process()` -- which both returns the next location in the path, and updates the array of points forming the path. 
    - Note how this is a simpler version of the code in `Movable.gd` that iterates through the entire array of points in the path returned by the Navigation Server. We've now offloaded keeping track of the path to the `NavigationAgent2D`.
- `NavigationAgent2D` is a helper node that builds on `Navigation2DServer`. Right now, we essentially have the same functionality as we did using the `Navigation2DServer` alone, but optimized. In order to see the similarities, try this: checkout the code at the beginning of this section and modify this line of code -- `Navigation2DServer.map_get_path(get_world_2d().navigation_map, global_position, goal_pos, true, nav_layer)` -- setting the fourth argument (the `optimize` flag) to `true`.

Great, let's keep going! Set the `Goal` property in the 2D Scene Editor for the `Pedestrian` as `%PedestrianGoal`, just as it was before with the other script. Let's run the script and see what happens.

<iframe width="560" height="315" src="https://www.youtube.com/embed/0Et6-gn6Dqc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

As you can see, the pedestrians are moving but still piling up behind the slow walkers. This is because we need to do one final step in order to safely avoid collisions along the path. 

Let's change a couple of things in our scene and script. 

Click on the `NavigationAgent2D` node in the `Pedestrian` scene tree, and go to the Inspector. Under **NavigationAgent2D**, find the **Avoidance** section and turn on `Avoidance Enabled`.

Also within the **Avoidance** section, set the `Radius` to `8`, the `Neighbor Dist` to `200`, and the `Time Horizon` to `75`.

Next, replace the call to `move_and_collide()` on the last line of `_physics_process()` with the following:

`$NavigationAgent2D.set_velocity(movement * delta)`

This is where the magic of `NavigationAgent2D` starts to shine. Calling `set_velocity` internally calls Godot's collision avoidance algorithm that adjusts the velocity of the node as it moves around obstacles. We didn't even have to think about how to make the people smoothly walk around each other -- Godot will handle it for us! Super cool.

Since the call to the collision avoidance algorithm is actually a callback, a [Signal](https://docs.godotengine.org/en/3.5/getting_started/step_by_step/signals.html) called `velocity_computed` is emitted once the calculation is done and the node can safely move. This signal also emits the result of the calculation called `safe_velocity`. Let's connect this signal to the script.

Go back to the `Pedestrian` scene and click on the `NavigationAgent2D` node in the scene tree. In the **Node** menu, under **Signals**, find the signal called `velocity_computed` in the **NavigationAgent2D** section. Connect it to the `Pedestrian` script.

<iframe width="560" height="315" src="https://www.youtube.com/embed/m2-QDD7Cvps" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Now, we can simply call `move_and_collide()` within the receiver method, using the `safe_velocity` calculated by Godot. Our final code should look like this.

```GDScript
extends KinematicBody2D

export (String) var goal
onready var goal_pos = get_node(goal).global_position
export var current_speed = 50
export var arrival_tolerance = 10

func _ready():
    # Tell the agent where it should navigate to
    $NavigationAgent2D.set_target_location(goal_pos)

func _physics_process(delta):
    # Similar to the car, when the pedestrian gets close enough to the goal, free it
    if global_position.distance_to(goal_pos) <= arrival_tolerance:
        queue_free()
    # Find the next point in the path to navigate to and update the internal path within the agent
    var next_location = $NavigationAgent2D.get_next_location()
    # Calculate the direction and movement just as before
    var direction = (next_location - global_position).normalized()
    var movement = direction * current_speed
    # Sends the movement input to the internal collision avoidance algorithm and sets the agent's velocity
    $NavigationAgent2D.set_velocity(movement * delta)
    
func _on_NavigationAgent2D_velocity_computed(safe_velocity):
    move_and_collide(safe_velocity)
```

Awesome, we're all done! Let's run our game and see the results.

<iframe width="560" height="315" src="https://www.youtube.com/embed/Zej8wi7VQ-s" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Some final notes about the `NavigationAgent2D`:
* Collision avoidance is not actually checking the collision layers of the `KinematicBody2D`. Instead, each `NavigationAgent2D` registers itself as an agent of a certain size with the `Navigation2DServer`, and it can see all other registered agents. 
* The size that the `NavigationAgent2D` registers itself with is its `radius` property (found in the **Inspector** under the **Avoidance** section). 
* The other properties in the **Avoidance** section relate to how the agent navigates around other agents. Before the tutorial, we tinkered with the values quite a bit before finding the right mix for our pedestrians. Take some time to play with the values on your own and see how it affects the end result!
* If a future project of yours has avoidable nodes that are dynamic but **should not** themselves move to avoid others, consider adding a [`NavigationObstacle2D`](https://docs.godotengine.org/en/stable/classes/class_navigationobstacle2d.html) as a child. For static obstacles, it is better to update the navigation map itself. 

## Conclusion
In this tutorial, we learned about Godot's completely new navigation system. They've implemented a system that is flexible and easy to use, especially for those new to game development. Furthermore, they've even given us a built-in way to handle static and dynamic collision avoidance using Navigation Agents, which is extremely powerful. 

We hope you've enjoyed this tutorial and gained a good understanding of how to use Godot's new Navigation System and its advantages. We hope you use this knowledge to go forth and create some awesome new games -- please share them below and showcase your work!

Follow this blog and our YouTube channel for even more tutorials. Let us know what other topics you'd like us to cover!