Thank you very much, I love you. I changed some code since I noticed that it will not detect tiles before (0,0). I'll leave it here if anyone ever needs it. And please correct me for improvement. Thank you. # This will output something like... (-9, -5), (19, 10) map_rect = Rect2i(get_used_rect().position, tilemap_size) # This will loop i value from -9 to 9, and j value from -5 to 4 for i in range(get_used_rect().position.x, get_used_rect().end.x): for j in range(get_used_rect().position.y, get_used_rect().end.y): # I also included the coords with no tiles to be un-walkable if not tile_data or tile_data.get_custom_data('type') == 'wall': astar.set_point_solid(coords)
I pinned this in case anyone else needs a tilemap that does not start from (0,0) I just realized you edited your comment. Much love to you too, brother! 🥜
Hey there! I just wanted to say thanks for using my assets It's really encouraging to see people using them to create something new, especially if it's something that helps other creators! I love your tutorials, you are really good at explaining complicated things in an interesting way! Thank you for making them! 💛
This video was a MASSIVE help in actually understanding how to set things up for my tactics game. Thank you so much for making this easily understandable
For Godot 4.3 and TileMapLayer you have to do/type the following things differently: get_tileset -> get_tile_set get_cell_tile_data(0, coords) -> get_cell_tile_data(coords) The rest should be fine.
for others with different tile grid sizes, you need to do to_local(map_to_local(position)) and to_global(local_to_map(position)) etc. to scale the tile correctly between global mouse coordinates and local tile coordinates...
I know there is a method `set_point_weight_scale` which, for each AStarGrid2D generated point, instead of letting the grid compute the cost normally, it also multiplies that cost with a weight. It might be just what you need. docs.godotengine.org/en/stable/classes/class_astargrid2d.html
This is such a good tutorial! I'm trying to do this with an isometric tilemap but I've had no luck. Would you consider making a tutorial like this one with an isometric grid? Keep up the great work!
Best explanation I've seen, helped me a lot. If anyone knows of a tutorial to set tile data to modify pathfinding based on speed, would appreciate. As an example, I want different tiles to modify character speed in them, and that the pathfinding accounts for it. Sorry complete newb using Godot, help is appreciated.
I'm really happy it helped you! I haven't tried your specific use case, but give some tiles a property and make the passing object have a certain speed when it passes through such a tile. However, keep in mind that there could be more and better ways to implement this. 🥜
One of the cool things in 4.3 is that you can do this with TileMapLayers so each layer has it's own grid. Then whenever you put something on a layer it'll know exactly which grid to use.
@@Alex95334 Try to write the following things differently, then it should work with TileMapLayer: get_tileset -> get_tile_set get_cell_tile_data(0, coords) -> get_cell_tile_data(coords) The rest should be fine.
Im trying to get your code to work for an Isometric grid. I cannot figure it out. I would love if you could make a tutorial on click movement on an Isometric grid.
@@cashewolddew That would be amazing! I actually got some movement to work from this video just now, but its wonky. So I cant wait to learn from you about Isometric movement. You explain things really well! Im trying to make a tactics game/mixed with Runescape skilling in a 2D Isometric grid. Super fun!
Hey there, love how easy it was to use the code, but I've been wondering: How can I check multiple tilesets for collision? For example, I have one Tileset for Ground Colors and another layer for plants/trees and such. Would I have to separate everything into its own Tilemap in the scene and check with each before I can actually add the new position? Thanks in advance!
I hope I'm understanding this correctly, but in this case it looks like you only need to set the custom data to be equal to whatever word you want in order to identify obstacles and then check against it and act accordingly. Hope this helps! 🥜
@@cashewolddew Oh no sorry, thats not what I meant. In the video, you only use one PNG for all tiles, but I have two pictures, which are two separate tilesets in the same TileMap object. But with the code as it is, the character just floats through the objects, even if their custom data has been set to blocking the path. I am sorry, I don't know how to best describe it in a comment
Maybe you could use 'get_used_cells_by_id' to access different layers and check their info. However, what I would do in your case would be to carefully analyze how my astar grid cells have been generated, which would, in turn, probably point me to a solution or a new direction.
@@cashewolddew Thanks for the ideas. For now I just opted to a hardcoded loop which checks every layer with get_cell_tile_data on a given coordinate. I don't like this solution to much, but I am only testing around anyway, so it will suffice for now :D Well once again, thank you for the Tutorial!
Could you please do a tutorial like this but for TileMapLayers? It would be sooo helpul! I'm trying to make this code work for TileMapLayers but am not able to.
If you want to see the path made by the algorithm you can always get the points array with 'get_point_path'. For each point, you can, then, use 'draw_circle' in your _draw() function to draw a point. Moreover, you can use 'draw_line' to draw lines between those circles. However, generally, there are more ways of doing something like this. This is the first thing that came to mind. If anyone knows a better way I'd be happy to hear about it 🥜
Great tutorial but I need a little help, I can't seem to get obstacles to work no matter what I do, I've copied your code to the letter and it didn't work for me, I've even tried some variations "is_point_walkable" returns true for the entire map no matter what I do
Maybe it could help to try the project I attached in the description of the video. There, you will find a working version. Maybe it will help you find out why yours isn't working. I'd be happy to see it work! ^^
@@cashewolddew The GitHub you mean? Maybe I'm missing something but I haven't been able to dl the project from github, I'm quite a newbie to these things
Thanks for letting me know. Generally what you would want to do is simply clone the repository. Afterwards you will be able to try any project you like. However, now that you say this, I see how it could be pretty cumbersome to get all projects at once, instead of only getting the specific ones. I'll try creating a guide for sparse cloning from Github. Thanks a lot for the idea!
Hi, I have the problem that I get this error: player.gd:58 @ _unhandled_input(): Can't get id path. Point (-4, -2) out of bounds [P: (0, 0), S: (24, 21)]. It seems I can't click anywhere on my map except the original tileset? But if I paint a big area I can't move there.
If you're generating the area at run-time, then you should be able to similarly expand the bounds of the AStarGrid2D area. I think, in general, you should be able to expand that zone based on your needs. Hope you get it fixed! 🥜
@@cashewolddew I tested it again and made a big area. It only moves into positives vectors. I move my map and now my player don't start at (0,0) but it works now.
Hi, do you know how to use "scene collections" instead of tiles with this method? They cant have "custom data" in tilemap so i tried adding "metadata" to original scenes (and changed "get_custom_data" to "get_meta" in script) but script still ignores them. Is there a way to reference these scenes?
Hey! I'm currently not familiar with scene collections, but I'll take a look when I get the chance and if I find a solution I'l let you know or make a video about it if it is more complicated.
Ha ha, that's a very exciting question actually! I just tried it out by adding a walkable tile around the wall tiles to the top-right and if you click on it... nothing happens. :D I tried some more configurations, but it doesn't seem to get stuck in any kind of loop or crash. It keeps working as if the tile would be unreachable (well, because it technically isn't reachable, being surrounded by walls)
Since there was no need for any other special physics processing I considered the best solution to be a custom data layer. However this is a matter of choice and it shouldn't stop you from using a physics layer instead if it fits your case better!
I would look for what is available in Godot 4.0 for AStarGrid2D. Here's a link for that: docs.godotengine.org/en/4.0/classes/class_astargrid2d.html If your project isn't too large, maybe it would also be worth considering migrating to a newer version.
Special thanks to you , after reviewing your page you gave me i know how to fix My code before : ``` var astar = AStarGrid2D.new() var map_rect = Rect2i() # Called when the node enters the scene tree for the first time. func _ready():
var tile_size = get_tileset().tile_size var tilemap_size = get_used_rect().end - get_used_rect().position map_rect = Rect2i(Vector2i(), tilemap_size)
astar.region = map_rect ``` After changing from 'region' i did this : astar.size = Vector2i(32, 32) It work perfectly i promise i will give u link after finish my project! 👍@@cashewolddew
new at scripting and godot here and wow this is so intimidating. how did you ever figure out all of this? HEURISTIC_MANHATTAN is not in my vocabulary so these words just throw me off completely lol
Don't worry too much about it. The Manhattan Heuristic is not even related to Godot. Heuristic is a term used in many fields and basically means a 'shortcut' or another solution to a problem. For pathfinding there are many heuristics which make the character behave slightly different with each one, and Manhattan is simply one of them. But look, you just heard about it. Next time you'll think about pathfinding you'll think that there are some heuristics which can be applied. At some point you might need to get more in depth and you'll find out about those as well. If you're interested in such topics check out www.redblobgames.com. It has very interesting reads.
Thank you very much, I love you.
I changed some code since I noticed that it will not detect tiles before (0,0). I'll leave it here if anyone ever needs it. And please correct me for improvement. Thank you.
# This will output something like... (-9, -5), (19, 10)
map_rect = Rect2i(get_used_rect().position, tilemap_size)
# This will loop i value from -9 to 9, and j value from -5 to 4
for i in range(get_used_rect().position.x, get_used_rect().end.x):
for j in range(get_used_rect().position.y, get_used_rect().end.y):
# I also included the coords with no tiles to be un-walkable
if not tile_data or tile_data.get_custom_data('type') == 'wall':
astar.set_point_solid(coords)
Great, thanks for the cool addition! 🥜
I pinned this in case anyone else needs a tilemap that does not start from (0,0)
I just realized you edited your comment. Much love to you too, brother! 🥜
Hey there! I just wanted to say thanks for using my assets It's really encouraging to see people using them to create something new, especially if it's something that helps other creators! I love your tutorials, you are really good at explaining complicated things in an interesting way! Thank you for making them! 💛
I should be the one thanking you! I am very happy to hear from you! ^^ Cheers 🥜
I thought working out grid-based pathfinding was going to take me all weekend. You're a scholar and a gentleman!
This video was a MASSIVE help in actually understanding how to set things up for my tactics game. Thank you so much for making this easily understandable
Getting comments like this is the main reason I'm doing these videos. Thank you so much and I'm so glad I was able to help you! 🥜
For Godot 4.3 and TileMapLayer you have to do/type the following things differently:
get_tileset -> get_tile_set
get_cell_tile_data(0, coords) -> get_cell_tile_data(coords)
The rest should be fine.
This is excellent work - absolutely got me up and running with Astar in Godot.
I'm very glad it helped you! Keep it up making cool games! ^^
good video bro, i was looking for this type of pathfinding for a long time
I'm very happy it helped you!
this helped me out a lot thanks. Pathfinding has always kicked my butt and hindered my projects but now I can do it!
The best explanation. Wow.
This is awesome. A very different technique I’ve never seen before.
Thanks for thr tutorial mr. Cashew!
for others with different tile grid sizes, you need to do to_local(map_to_local(position)) and to_global(local_to_map(position)) etc. to scale the tile correctly between global mouse coordinates and local tile coordinates...
Thanks for the cool tip!
Thanks for the video, was very helpful!
Hey mr. Cashew! Liked and subscribed :)
Do you know if it is possible to put the cost to every tile and let the algorithm take that into account when finding a path?
I know there is a method `set_point_weight_scale` which, for each AStarGrid2D generated point, instead of letting the grid compute the cost normally, it also multiplies that cost with a weight. It might be just what you need. docs.godotengine.org/en/stable/classes/class_astargrid2d.html
Great tutorial!
This is such a good tutorial! I'm trying to do this with an isometric tilemap but I've had no luck. Would you consider making a tutorial like this one with an isometric grid? Keep up the great work!
Thanks a lot for the suggestion! I'll look into it and come back with a tutorial if I find it fitting! ^^
@@cashewolddew Thank you so much!
Best explanation I've seen, helped me a lot.
If anyone knows of a tutorial to set tile data to modify pathfinding based on speed, would appreciate. As an example, I want different tiles to modify character speed in them, and that the pathfinding accounts for it.
Sorry complete newb using Godot, help is appreciated.
I'm really happy it helped you!
I haven't tried your specific use case, but give some tiles a property and make the passing object have a certain speed when it passes through such a tile.
However, keep in mind that there could be more and better ways to implement this. 🥜
Very useful; thanks!
One of the cool things in 4.3 is that you can do this with TileMapLayers so each layer has it's own grid. Then whenever you put something on a layer it'll know exactly which grid to use.
I can't wait for 4.3! I'll make sure to update these tutorials because that version makes things much simpler. 🥜
How??? I've been searching for hours on how to do this!
@@Alex95334 Try to write the following things differently, then it should work with TileMapLayer:
get_tileset -> get_tile_set
get_cell_tile_data(0, coords) -> get_cell_tile_data(coords)
The rest should be fine.
Hey, could you update this tutorial considering tilemap layers? 🙏🙏🙏 Thank youuu
Will do, for sure! 🥜
@@cashewolddew awesome!
Im trying to get your code to work for an Isometric grid. I cannot figure it out. I would love if you could make a tutorial on click movement on an Isometric grid.
I have planned an isometric Tilemap tutorial. I will look into it and include that as well. Thanks for the suggestion! 🥜
@@cashewolddew That would be amazing! I actually got some movement to work from this video just now, but its wonky. So I cant wait to learn from you about Isometric movement. You explain things really well! Im trying to make a tactics game/mixed with Runescape skilling in a 2D Isometric grid. Super fun!
@@highpriestessmoon That does, indeed, sound really fun!
Hey there, love how easy it was to use the code, but I've been wondering: How can I check multiple tilesets for collision? For example, I have one Tileset for Ground Colors and another layer for plants/trees and such. Would I have to separate everything into its own Tilemap in the scene and check with each before I can actually add the new position?
Thanks in advance!
I hope I'm understanding this correctly, but in this case it looks like you only need to set the custom data to be equal to whatever word you want in order to identify obstacles and then check against it and act accordingly. Hope this helps! 🥜
@@cashewolddew Oh no sorry, thats not what I meant. In the video, you only use one PNG for all tiles, but I have two pictures, which are two separate tilesets in the same TileMap object. But with the code as it is, the character just floats through the objects, even if their custom data has been set to blocking the path.
I am sorry, I don't know how to best describe it in a comment
Maybe you could use 'get_used_cells_by_id' to access different layers and check their info. However, what I would do in your case would be to carefully analyze how my astar grid cells have been generated, which would, in turn, probably point me to a solution or a new direction.
@@cashewolddew Thanks for the ideas. For now I just opted to a hardcoded loop which checks every layer with get_cell_tile_data on a given coordinate. I don't like this solution to much, but I am only testing around anyway, so it will suffice for now :D Well once again, thank you for the Tutorial!
Could you please do a tutorial like this but for TileMapLayers? It would be sooo helpul! I'm trying to make this code work for TileMapLayers but am not able to.
I'm looking into updating all tutorials that become outdated. Thanks for staying tuned in by subscribing! 🥜
Is there a way to visualize the A*Grid after it's been made?
If you want to see the path made by the algorithm you can always get the points array with 'get_point_path'. For each point, you can, then, use 'draw_circle' in your _draw() function to draw a point. Moreover, you can use 'draw_line' to draw lines between those circles.
However, generally, there are more ways of doing something like this. This is the first thing that came to mind. If anyone knows a better way I'd be happy to hear about it 🥜
Great tutorial but I need a little help, I can't seem to get obstacles to work no matter what I do, I've copied your code to the letter and it didn't work for me, I've even tried some variations "is_point_walkable" returns true for the entire map no matter what I do
Maybe it could help to try the project I attached in the description of the video. There, you will find a working version. Maybe it will help you find out why yours isn't working.
I'd be happy to see it work! ^^
@@cashewolddew The GitHub you mean? Maybe I'm missing something but I haven't been able to dl the project from github, I'm quite a newbie to these things
Thanks for letting me know. Generally what you would want to do is simply clone the repository. Afterwards you will be able to try any project you like.
However, now that you say this, I see how it could be pretty cumbersome to get all projects at once, instead of only getting the specific ones. I'll try creating a guide for sparse cloning from Github. Thanks a lot for the idea!
Hi, I have the problem that I get this error:
player.gd:58 @ _unhandled_input(): Can't get id path. Point (-4, -2) out of bounds [P: (0, 0), S: (24, 21)].
It seems I can't click anywhere on my map except the original tileset? But if I paint a big area I can't move there.
If you're generating the area at run-time, then you should be able to similarly expand the bounds of the AStarGrid2D area.
I think, in general, you should be able to expand that zone based on your needs. Hope you get it fixed! 🥜
@@cashewolddew I tested it again and made a big area. It only moves into positives vectors.
I move my map and now my player don't start at (0,0) but it works now.
Hi, do you know how to use "scene collections" instead of tiles with this method? They cant have "custom data" in tilemap so i tried adding "metadata" to original scenes (and changed "get_custom_data" to "get_meta" in script) but script still ignores them. Is there a way to reference these scenes?
Hey! I'm currently not familiar with scene collections, but I'll take a look when I get the chance and if I find a solution I'l let you know or make a video about it if it is more complicated.
@@cashewolddew Thanks! I will write here if i will find the answer myself.
@@SmutnyReptyl That would be highly appreciated! :D
What happens if you click an unreachable tile? for example a walkable tile surrounded by wall tiles.
Ha ha, that's a very exciting question actually! I just tried it out by adding a walkable tile around the wall tiles to the top-right and if you click on it... nothing happens. :D
I tried some more configurations, but it doesn't seem to get stuck in any kind of loop or crash. It keeps working as if the tile would be unreachable (well, because it technically isn't reachable, being surrounded by walls)
@@cashewolddewgood to know it handles that gracefully
Why do you use custom type wall rather than using a physics layer?
Since there was no need for any other special physics processing I considered the best solution to be a custom data layer. However this is a matter of choice and it shouldn't stop you from using a physics layer instead if it fits your case better!
Hey, godot 4.0 for astar2d doesn't has 'region' what can i do ? please sir help me
I would look for what is available in Godot 4.0 for AStarGrid2D. Here's a link for that: docs.godotengine.org/en/4.0/classes/class_astargrid2d.html
If your project isn't too large, maybe it would also be worth considering migrating to a newer version.
Special thanks to you , after reviewing your page you gave me i know how to fix
My code before :
```
var astar = AStarGrid2D.new()
var map_rect = Rect2i()
# Called when the node enters the scene tree for the first time.
func _ready():
var tile_size = get_tileset().tile_size
var tilemap_size = get_used_rect().end - get_used_rect().position
map_rect = Rect2i(Vector2i(), tilemap_size)
astar.region = map_rect
```
After changing from 'region' i did this : astar.size = Vector2i(32, 32) It work perfectly i promise i will give u link after finish my project! 👍@@cashewolddew
@@Fixed_Venus I'm glad to hear that everything works well now! I'd be happy to see your project afterwards 🥜
new at scripting and godot here and wow this is so intimidating. how did you ever figure out all of this? HEURISTIC_MANHATTAN is not in my vocabulary so these words just throw me off completely lol
Don't worry too much about it. The Manhattan Heuristic is not even related to Godot. Heuristic is a term used in many fields and basically means a 'shortcut' or another solution to a problem.
For pathfinding there are many heuristics which make the character behave slightly different with each one, and Manhattan is simply one of them.
But look, you just heard about it. Next time you'll think about pathfinding you'll think that there are some heuristics which can be applied. At some point you might need to get more in depth and you'll find out about those as well.
If you're interested in such topics check out www.redblobgames.com. It has very interesting reads.