Point & click 2D grid movement in Godot 4 using AStarGrid2D

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome back to another tutorial um today we're going to be looking at how to make a character move on a town map grid using the a-star grid 2D functionalities and also how we can utilize custom data layers in tile maps to determine where a player should be able to move and how to alter the a-star pathfinding based on the settings so let's get started all right so all I've done is create a new 2D scene set it as the main scene and I've also import the tile map that we're going to be using I'll provide a link in the description and before we start since we work with pixel art we're going to have to change a couple of things let's set the window size first like so and then set the stretch mode to Canvas items in an under rendering we also need to change the default texture filter to nearest to get clean pixel art okay now that we've done that we can start making detail map create a newtel set drag in your tail map yes we want to cut them up and then you can just draw a quick tail map over to tell map click a tile and let's add some some trees okay that's it for the tile map then we're going to add a new note to D which is going to be the player and he's going to need us right and he's also going to need a camera 2D and for the Sprite we're going to use a new Atlas texture and we actually have to drag it in edit the region we're working with a tail set that's 16 by 16 pixels click this guy okay let's move this node to V into the middle of a into the middle of the a tail map cell so let's see is this the middle one down there we go so now it's in the middle the tail map that's good okay then we can start adding a script and we're going to be doing a couple of things in here we're going to have to listen to input we're going to have to initialize the a star grid to the object and we're going to have to move the player once there's a path available um so let's start with the initialization of the a-star grid going to be an a start with 2D object and we're doing this so that we have a reference to the grid that we set in all of our functions we won't be using process and in the ready function we're going to create an instance of this object new okay and in order to align our a-star grid 2D with our tail map we need to set the region of the grid equal to the use rectangle of our tile map in order to make our cells align so both the telomapp cells and the a star grid to the cells and we can do that by getting a reference to our tail map and then we're going to say a start grid dot region I'm gonna set this to Tau map.getused correct we're also going to set the cell size which is going to be a vector 2. it contains of 16 by 16 because our tail map is 16 by 16 pixels we're going to set the diagonal mode which means that the a-star pathfinding algorithm will be able to find diagonal moves we don't want that we only want the player to move left or right or up or down and we can do that by setting diagonal mode to never like so so we've changed a couple of things on the a-star a-star grid to the object and especially for the region and the cell size we need to call the update function on this object in order for it to be processed okay so that's our grid then next up we're going to make the function for listening to the input and again event in this function so let's also make an action called move and we're going to bind it to the left Mouse button so if event dot is action pressed move is false then we don't want to do anything but if it is the move so if we click then we're going to get into this function uh and what do we want to do in this function in this function we want to get the path towards the mouse Point clicked and we can do that by saying for our ID path which is going to be the result of this function call on the grid get ID path which will return a array of vector 2ys which correspond to tiles on the tile map as well as tiles on the actual Acer grid 2D you should basically see the a-star grid like a separate tile map over your existing tile map but it only stores the coordinates and it serves um as a for navigation purposes only and what we're going to do is we're going to when the player clicks somewhere we're gonna translate the global position to a vector to y and then let the a star grid determine how it needs to walk there and when we want to get a path it takes two parameters it takes a from ID and A2 IDE so we need to get two vector2i's the position where we want to navigate from and where we want to go toward but we want to navigate from the position that we are so we can translate our Global position to a vector 2i using the tile map so we're going to say tell map a local to map which means we're going to convert a vector to Global position to a vector 2i see this function requires a vector 2 so it's going to be Global position of the player object and then the second variable is going to be the two the vector 2i so we're going to have to translate the global Mouse position when you click to a vector 2i and we can do the basically intel map local to map and then we can say get Global Mouse position yeah all right let's see what it returns so when I click below our character we get the current position and the position that we want to go to if I click on the character we got only our current position and the further I click the more notes we get because the path is going to be longer well we don't want to get the first position we only care about the positions that we want to go to so in order to do that we're going to slice this result which will remove the first item in the area so when I click next to us we only get the position that we want to go toward that's good all right so we have our path now to actually start moving we're going to have to set another variable because we're going to be moving in our physics process function I'm going to call this current ID F and it's going to be an array of factor two eyes because that's what this function returns um so if ID path is empty a is false because if we click on ourselves we have nothing to know where to go so we don't want to set this to an empty array we're gonna if it's not empty our current ID path is ID path right so now we have our path stored in this variable then let's start moving by setting up the physics process function uh and this physics process function is going to be called every physics frame but we don't want to do anything if there's no path set so if our current ID path is empty return if it's not empty however we want to start moving and we're going to have to move our player to a vector 2 position because we can't move our player to a vector 2i position so first of all we're going to set a Target position variable and that's going to be equal to the first item in our current ID path but we have to convert it to a vector2 and the Tau map actually has a function for that to Maps a local and we can pass in the first item of our current ID path by saying kernel dpath.front Returns the first item now we have a position we want to move to let's move our players our Global position is global position dot move toward and we want to move toward our Target position and then also a speed so let's say one okay we should already be moving one tile now if we click somewhere yeah so it moves one tile but we want to Loop over all the points in our vector2y array and then keep on moving because we have all the positions stored in our little array over here so we move to our next position and then after we've done that we want to check if we've arrived at the set position which is the first item of our current ID path so if Global position is the same as Target position then we wanna pop the front of the array of paths because we want to continue to the next item in that area I think we can say pop front yeah so pop front will remove the first item of the array which means the next iteration Target Position will be something else yeah so you can see we're already moving on the grid toward our Target position and as you can see we can move over obstacles that that's not really what we want and if you spam click you can even see that we can kind of Glide around because we're not making sure that the when you're moving the next move should be from the next Target position and we don't do that right now so let's see uh how we can fix being able to move over obstacles and how we can also fix getting off the grid all right so how are we going to determine if a player should be able to walk over a certain towel or not and we're actually gonna do that by adjusting our a-star grid to the object or telling it which tiles are going to be solid and solid means that it won't be using the cell for calculating the navigation that needs to take place and we're going to do that using a custom data layer so go to your tile map go to your tile set add a custom data layer that's called walkable it's going to be a Boolean because we're going to assign a value to separate tiles in your tail map um go to your tell set go to paint and select the walkable custom data layer and now we're going to tell this tile set that these four tiles we only use this one but these four tiles will have this value set to true and we can use it in the script to tell the ASR grid okay we're going to be looping over all the tiles and if this value is false then disable this over navigation so we've set this data now we can actually go to the script and we're going to start by looping over every cell in the tail map and we can do that by taking a look at this value this function will actually return a sleep position the initial position so this is the top most left point of the tile map and also the size in tiles and we're going to be looping over these two values in order to Loop over all the available tiles and we can do that by saying 4X in delmap.getusrect dot size dot X that we was that was actually what the S was for you can see that in here rect2i has to well actually three but two properties that we're going to use position and size and we're right now going to Loop over the size of the um rectangle of the Tau map so we're going to do this for the x-axis we're also going to do this for the Y value so now we should be looping over every single tile that is available within our rectangle and we're going to be converting these two values to a vector 2y because we want to know the top position vector 2i and then we can just say x value and Y value this is not correct but we're going to run into what's going to happen soon so maybe I can explain it a little easier now that we have the tile position we want to get the walkable tile data right so we're going to say tell data first we have to get the tell data object get data or something get cell tailed yeah player zero we didn't change anything and then the tile position we want to get the tile data for this style and if tell data is null which means there's no tile there or if cell data dots get custom what is it get to some data and it's going to be our walkable data if we're not allowed to walk on this because it's false then we're going to tell the a star grid that it needs to set this cell to solid so we're going to say a star grid dot set point solid and it needs a position so that's going to be the third position and it needs to be set to true but it's the default value so now this position in the tail map on the a star grid it's going to be disabled for navigation and I think the best way we can check this is just by going in and you can see it's not working and why isn't it working well that's because these values these X and Y values are not relative to the offset of the tail set so in the first iteration of these both Loops X is going to be zero and Y is going to be zero and that will translate to this title and that's not what we want we want to start on the topmost left tile and then scan every tile right now it's doing it from the wrong offset and in order to do that we need to go into here and we want to offset this by the second value in this function and there's going to be position dot X and we're going to do the same for y and these could be minus values this could be positive values as long as they get applied to the correct position now we can actually get the correct tile right and we shouldn't be seeing any errors now and if I click somewhere it will now actively Dodge the trees because they're walkable value is uh set to fall so when I click now he will find a way around the cell that has been disabled and if we go to the edge of the map we've also covered these cells because they don't have data so when I click here nothing happens but they are inside of our a-star grid but they're just disabled so we will also Dodge them so that way you don't have to have a perfectly Square Tile Maps because if there's no title tile data available we will just disable it in the a-star grid and now there's still the issue of swim clicking and then going off the grid because we don't set the correct path from the next Target position so let's take a look on how we can fix that in order to fix the the fact that we can still slide around we need to make sure that we only set the target position directly if we're standing still and then we also have to make sure that once we arrive at a destination that we set the target position if we see that the array that we've adjusted is not empty and apart from that we also need to calculate a path from the target position if you're moving because if you're moving already and you click somewhere else we want to update this variable with a path that is calculated from the position you're going to be arriving at so that we can immediately continue moving um so how do we do that we first start off by making the target position available to the entire script and then we're also going to use a flag for determining if we're moving yes or no okay let's start in the physics process so if it's moving is false then we want to set the target position because if we are moving we don't want to do this and now in order to determine if we're moving we're going to say it's moving it's true over here because we weren't moving but now we are and then beneath the fact that we check like we changed the current ID path variable once we reach our position because we pop it now we also have to select the next value and put it in a Target position because right now we move one tile we stop because we don't do this anymore we don't do this every frame we used to but now we do it only when we're not moving so in here we're going to check if the current d-path is empty and if that's false then we're gonna be saying uh current uh Target position is current ID path we actually have to convert this because this is uh we need to convert it to a vector 2. so we can use detail map for that map to local and then we pick the first item was it first front front now when we have arrived we see it's not empty okay let's let's go to the next tile it's basically a loop um but if it is empty then we're done moving so moving going to be false okay now in order to determine which or where to start our path generation from we need to um check if we're moving when we're going to get a new ID path so let's make this variable like so and then we're gonna check if we're moving if we're moving we actually don't want to do this from our Global position we want to make a new path from the target position and if we don't want to slice that because otherwise we're still going to be able to move diagonally and otherwise it's just going to be what we already have so is going to be calculate a path for my Google position however moving our starting point will be our destination and if we're not moving we use our current position as the starting point otherwise it's going to be the target position and this should be it yeah so now I can I can spam click you can see that it it has to finish moving to its targets before it actually um gets the newly set Target position Y is which is coming from the array that we overwrite basically uh yeah so now we have both the cell map data and the fact that we wait for the navigation to finish before we actually um use our new path and for a bonus let's look into how we can draw a line in order to visualize where we are going in order for us to start drawing a line to where we're moving we're gonna need another resource that is being provided by the a-star grid and that's going to be a Point path which is basically an area of vector twos actually it's effect Vector 2 array and we're going to pass it into another script which will draw the line for us based on the positions of the vector twos in this array and in order to fill this array we're going to in the input function when we determine that the path is not empty we're going to set this variable current Point path is a star grid dot get Point path and it needs two Vector two eyes again so let's just pass in the Target position and the mouse position again because we still need the these values so now we've set this value we're going to create a new node which is going to be responsible for Drawing the Line let's call this uh uh bath add a script and all that we're going to do in here is we're going to make a function draw we're going to need a reference to the player because if there's no point path we don't really care if player don't point insurance Point path if it's empty return if it's not empty we're going to draw a what is it polyline yeah this function actually wants a packed Factor two array which is what this is so we can pass it in and then it also wants a color let's do a color.red it wants a color to draw the line and in order for this function to be called we need to call another function in the process of this script which is called Q redraw now this will be updated every frame so if this value changes then the correct line is also drawn okay let's check it out so you can see that the offset of the line is now the position is now on the top left of the towel that we're moving on so we might have to add some offset and we can do that by adjusting the values in our current Point path by going to the player and after we've actually set this value we're just going to Loop over it so for I in current Point path dot size we're gonna set the failure we're currently looping over to a value plus half of the size of our tile set so plus Vector two we use 16 by 16 so eighth and eight so now it should be centered in our tile and it is so now you can see the path that we're gonna move that the a circuit determines you should move you can see if we click rapidly it changes path but we still uh have to wait until we're done moving so I think that's it I hope you learned something this might be a bit of a heavy topic but I hope it uh it was all clear thanks for watching and let me know what you want to see next
Info
Channel: Retrobright
Views: 21,906
Rating: undefined out of 5
Keywords: Godot 4, Godot, Game Development, Tutorial, Easy, Beginner, Tilemap, custom data layers, AStarGrid2D, Pathfinding, Movement, 2D movement, A*, AStar, 2D
Id: DkAmGxRuCk4
Channel Id: undefined
Length: 24min 33sec (1473 seconds)
Published: Mon Sep 18 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.