Pathfinding on a TileMap with Navigation2D (Godot 3.1 tutorial)

  • 🎬 Video
  • ℹ️ Published 4 years ago

We made 2 tutorials together with Chris aka KidsCanCode to help you do pathfinding with tile-based maps in Godot 3.1.

💬 Comments

16:21 I think condition "elif distance < 0.0:" will never be true, so the whole block won't be executed. Maybe you can use something like "elif path.size() == 1 && distance > distance_to_next:" instead.

Author — Asterix Xavier


If you have a camera following the player, the solution has been obscurely stated below. Here is how to do it:
In your Node script, in the variable new_path, change out event.global_position with

Author — Joseph K


Thanks for the videos. Please note that the for loop in the move_along_path function is unnecessary. A better implementation is as follows. Please try it and see.

func move_along_path(distance: float) -> void:

if distance<=0 or path.size()<=0:

var dist_to_next := position.distance_to(path[0])

if distance<=dist_to_next:
position = position.linear_interpolate(path[0], distance/dist_to_next)

Author — M Barake


How would one combine this to include collision detection while moving along this path? Or use the pathfinder to take collisions into account?

I have my collisions all set up in the tileset, but a kinestatic2d isn't going to do much with them unless included in the code with move_and_slide or move_and_collide.

You help would be much appreciated, and this topic could maybe make a great part 2, if it is complicated enough for a video :)

Author — Stefan van der Ree


I am currently working on a simple 2d tower defense game, where the towers can be placed anywhere on the map. The path for each enemy from its spawn to its goal is calculated using the getsimplepath method, provided by the navigation2D node. What I would like to do now, is checking, if there is still a possible path, before I place a new tower on a certain position. In other words, I would like to know, if a tower blocks the path, before I even placed It on the field.
Does anyone know, if it is possible to do that?

Author — Jay Comedy Director


This is a very solid tutorial with a lot of good explanations of code practices throughout. You deserve more subscribers!

Author — Jacob Cowan


Thanks for the very informative tutorial. I have a similar pathfinding code for navigating around the map but one thing which am finding difficult to figure out is how to make pathfinding also pick up enemies so that the don't get stuck and will pathfind around an enemy. I am using KinematicBody2D nodes for my player and enemies. Thanks

Author — frasanderson


Hi! Great tutorial! I just wondered... in our case, and i think there are many others in the same situation, we use tilesets like the ones RPG Maker uses consisting of tile-filling tiles and kinda semi-transparent tiles supposed to be placed on another tile-layer above the ground layer. So there are at least two layers (3 to 4 in our case). First, is Navigation2D able to pull the nav-polygons from multiple child node tilemaps?
Another issue would be the situation of the tiles i described, on the ground layer i would place a normal "accessible" grass tile with a nav polygon on it, but on the layer above i'd place something like a rock (semitransparent but not accessible). The navigation2d would now only find the nav-polygon of the grass tile and my char would move through the rock like a ghost. Am I missing something? :o
I don't think it would be a good solution to maybe merge the rock tile with every possible accessible floor tile only to use just one tilemap for navigation :/

Author — Christian Klages


Great stuff, thank you so much.
Could you give me an idea how to take into account tiles that are occupied by enemy nodes, currently these enemies will be walked through as they don't have navigation added to them.

Author — Darryl Wainwright


Thank you for tutorial, it is great. But I have two questions abouit move_along_path-function.

First, is changing function attribute values inside function good practise?

Second, is changing looped object inside of for-loop good practise as well?

I think both are very dangeryous practises. They both might lead to very difficult bugs if there is need to extend function later.

Author — TheHamahakki


This is great but my tilemap's navigation isn't. It wasn't working so I turned on "Visible Navigation" in the debug settings and saw there was a grid like pattern between each tile. When I increase the size of the tilemap, creating tiles bigger than the player, the ai perfectly followed me because we were in the same tile. Any fixes for this???

Author — MaxFlyMan


Thank you for your time and effort !
A great video as usual.

Quick question if I may :
When using this method if you move the character "diagonally" on an obstacle free path, the character won't do a simple line between the two points but will follow two lines with an odd angle.
I saw in the doc that the path was optimized by default (setting this parameter to false get even stranger results).
Do you know of a simple way to smooth those trajectories even further ? (ie only having single line trajectory when navigating an obstacle free path)
Note : I'm talking built in solution. If none exist, don't trouble yourself by creating something, I'll try to figure it out by myself after a good night rest ;) (probably by merging this method with some raycast shenanigans)

Again, Thank you so much for your trouble!
Et plein de courage pour la suite !

Author — Bananeisafree


Would this be easily applied to a enemy? So he could follow the player?

Author — Hollis Neufeld


Morning, I was wondering how ressource intensive that path calculation is. If I have a dozen enemies on screen, is calculating a new path towards the player each frame a bad idea ?

Author — MUDU mudu


Hey thanks for this tutorial it's very useful. I'm having a problem when I click in the screen, The line is not created where I click. I tried creating a polygon navigation and use navigation in tiles but it's nor working.

Author — Cesar Fernandez


thanks for the guide, was looking for it soo hard, but how could i do it for android version? i meant using touch not with buttons

Author — Mr Khai Tv


This works well when you are in control of the position like that of in a sprite, but what about when you are using a kinematic body? I don't know how to tell when it's reach the first point for it to change direction?

Author — C P


when I insert code character.path = new_path I get this error:

Invalid set index 'path' (on base: 'Sprite') with value of type 'PoolVector2Array'.
In fact, the closest suggestion from godot engine was get_path(). But character.get_path() cannot be assigned to new_path.
What am I doing wrong?

Author — Ashis Roy


Thanks for the tutorial!
I've a question. What's the benefits of doing (abbreviated code)
"IF not event InputEventMouse: return" and "IF not button left or not pressed: return"
and not doing
"IF event = mouse AND button = left AND is presed: //do things ELSE: return ?
even though it is something that is usually done in phyton.
Also in set_path function, you did "IF value.size...: you didn't use the ELSE statement.
I know it works the same way, but, Is there any benefit in doing it that particular way?

Author — Julian Guerra


Is there a way to implement this into a top down game which only uses horizontal and vertical movement?

Author — Galactic Quasar