How to make Rimworld in Godot 4: Pathfinding & Pawns

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
good day guys welcome to the second video in this series today we're going to work out how to do some path finding so you see we've done some different terrain we've got our nice grasslands our lowlands here and the idea is the darker areas as you go up the mountain so what I'm going to do first is try and make a a path finding which will find it really easy to walk on the grass and as you get higher it'll be a bit slower and more difficult which means if you wanted to walk from say up here in the top left to the top to the bottom right rather than walking a direct line straight across a little gu is going to want to walk through the nicer areas maybe he'll cut across here but he'll stick to the easier to walk areas and we'll put in some actual barriers and walls and trees and things later but um what we're going to do is actually every little square is going to have a cost and the pathf finding will look at the cost of each one and use that to work out the best way to get there now the good thing is about gdau the path finding is all built in I thought when I came into this I was going to have to write my own AAR algorithm which is a really common pathfind algorithm which is what's built into this one but it's already built in so we're not going to have to do it so here's how we're going to go about it so I'm just going to make a little child node here and it's just going to be any kind of node make it the Base Class node and we're going to call it path finding and this is just going to hold all our pathf finding scripts so let's add a script to that call it path finding and the first thing I'm going to do is give this access to our terrain so on ready bar terrain and our terrain we just drag it from over here so now we've got this variable terrain which we can refer to which we talk directly to our terrain so the pathf finding can actually find out what the terrain's like that we're walking over and what we need to do is actually have a reference to the AAR grid class as far I'll going call it AAR grid and we just refer to you got AAR 2D 3D and grid we're making a nice simple grid based game so we're using the AAR grid 2D the other ones work pretty similarly but let's use the one that works for us so let's make a new instance of that and I'm going to make just a little variable here to hold our path after we make it now the path is just going to be an array of vector 2D so a little array of positions so an empty array there so the first thing we need to do is initialize our path finding which means we've got to let the path finding have access to our terrain and know what it's actually doing so we just have to first of all tell it how big it's going to be a star grid set the region size and we'll set it by a rectangle so position doesn't matter CU we're just telling it the size and we're just going to grab our terrain do map width and our terrain. map height which that's referencing the height and width of our terrain now we need to tell it how big our actual cells are so our cell is one unit our one little grid there so for this they're 16 pixels each which is what we made them so let's go back to pathf finding oops path rting in the script and we just go AAR grid cell size there a vector 2 16 by 16 so you can actually have you know rectangular grids and then we'll just update that and the final thing we need to do is a loop through every s oh did I do that yeah final thing we need to do is Loop through every single position and tell it what's in there now it doesn't need to know if it's grass mountain rock whatever but it needs to know how difficult that spot's going to be so we have to add that difficulty now and the way we do that is with custom data on our tile set so go down to tile set and click one of these guys and you've got the coordinates animation we want to go over to the right and you've got your custom data layers and we're going to add an element and we're going to call it um let's call it cost now let's call it difficulty so it's easier for us we could even let's make it really obvious walk difficulty and it's type is going to be a float so what it's going to be is higher numbers it's going to be a higher cost and we'll use that little number to multiply our walk speed as well so if it's a really easy walk we'll walk fast but if you're walking this one it'll be slower slower slower now if you go down here You' got custom data now and what we need to do is for each type of terrain we need to click on that and so let's make our grass one just standard this one we're going to make it a bit more difficult 1.2 let's make the ground 1.5 let's make the Rocks a bit harder let's make it three and then the snow let's make it really hard let's make it eight so like everything we do here these things you can come back and Fiddle with later and you might want to have different terrain types you can even have you know you could have cement a bunch of other ones you could have a road which might be 0.8 but this allow us to get started and we can tweak things from there and make it prettier so now that that custom done is there we can go back to our script and we're going to Loop through every single point in the grid for X in range terrain map width for y in range map height now getting access that now getting access to that custom data is actually a pain in the butm and it takes a few lines of code so I'm not not going to write it directly in here I'm going to go down the bottom and I'm going to make an actual little script to grab that difficulty and I'll show you what I mean in a second so I'm going to make a function called get terrain difficulty whoops get terrain difficulty and we'll just add the coordinates in it and we're going to set the layer equal Z and we got to get the ID of the cell terrain. getet cell Source ID Source it's going to be the type tile set Atlas source then we're going to grab the atlas coordinates which is what we got here that's 0 0 0 1 02 sorry 0 0 1 02 0 is the position in our Atlas and now finally with all that we can grab the data TI data equals Source get tile data we give it the coordinates and the data we want is number zero so you can put in a bunch of different data points here we want the first one which is the zeroth one and then we'll return the tile data get custom data and now we give it the actual name of it and I just realized I've WR data instead of data sorry and I called it walk difficulty oh my gosh work difficulty all right let's see if that worked what I'll get it to do is I'll Loop through every single one and I'll just print get terrain difficulty for um Factor 2 I XY so what this should do is Loop through every single square and just print the difficulty so we get should get a list of 1es 1.2s 1.5s Threes And eights and it'll run on start so let's just um go to Output let's R run it and see if she works nice yeah that's definitely what we want all right so all we need to do now is instead of printing that we're going to pass it into that AAR grid so that that's the data that AAR grid will work from so what we do is we just go AAR grid set point weight scale and we tell the coordinates which is Vector 2 I XY and then we pass it the difficulty x y and that's it that's all our grid needs to know we don't have any walls or impassible places yet so we just need to we can put in impassible ones by going AAR grid. set point solid and give it the vector 2i so if you did that that would actually make all of them imp passible so we're going to just leave that there for later we'll definitely use that for something all right so that will settle that and now what we need to do is actually build a path and just a test what we'll do is we'll set a start and let's make Vector to I let's just make it 0 0 to start off with an end and let's just make it 78 23 just something random just realiz that should Vector 2 I and now we just request the path so we go path if you recall path is our variable up here equals and we just go AAR grid. get Point path from start to end and that's it that's literally all we have to do we've set up our grid and requested a path and we should get it and just to see if we've got it we will draw it so this is optional but it will help us test things so we just go function draw and we'll just go if length of path is greater than zero so basically if there's any path whatsoever then we'll Loop through the path and we'll just draw a line path number I to path number I + one I just realized we don't want to go through the whole thing we need to go minus one oh I forgot to tell her what color to be let's make it purple oh I just realized of course I can't run drawline because that's not built into the basic node that only works off a node 2D so let's just quickly change this to a node TD 2D so I'm just going to grab all this copy it let's delete path finding delete that node let's make a new one and let's make it a node 2D silly me node 2D call it path finding attach a script call it pathf finding basically we should have changed that one to that or you can paste in the old one make sure there no 2D and save it there let's see if that's going to work and there we've got our line um we can't really see where it's coming from and going to so let's just fix our camera to something a bit better so right now we're just seeing that square there let's zoom out and see the whole thing so I'm just going to add a camera here ADD child node camera 2D and let's shift it down here Zoom it right out there we go go a path from 0 0 to over there what did I say it was 78 23 all right let's fix it up so we can test it right here in the editor so what we're going to do is as we did last time make this into a tool rather than doing this on ready let's break it out into a function So Def init path finding so all the initialization stuff we'll steal from there sorry def different language funk now the start and end let's put them in here start equals let's say end and let's export those so that we get them in the um editor the inspector I should say and let's make a button calculate and that'll be a ball so when we click that that'll tell it to go and compute for us so in process let's just go if calculate equals false and then we will find path so let's make that find path and that's where we just go this one let's delete those guys oops not path pass oops I got calculate wrong and since I've just turned this into a tool before it'll work I have to actually go and reload the current project so let's do that now okay so if I grab my path finding now I've got a start an end and calculate so let's see let's make it start at 55 finish at 64 64 when I press calculate you can see it's going automatically turning off so the button's working it is actually doing our path but it's not drawing it for us so what we need to do is go back and make sure it actually so the draw function is still there it's still going to draw the path but nothing is telling it to to call it again so we need to tell it to so what we'll do is after we find a path we'll just go Q oops Q redraw and that will tell gdau that it needs to run draw again at least in its next draw pass so when to press calculate now oh why isn't that working let's make sure it's actually drawing can't get ID path point five out of five out of bounds five out of five is out of bounds oh I know I'm not actually calling initiate pathf finding there we go so now all right I think the problem is I'm running in the editor so it's not actually calling this one so what I'll do for now let's just add that to the button as well is a terrible slow way to do it if we're playing around in the editor for now it's fine so now I can just calculate and there we go and let's change that over there and you can see to get to here it's actually gone around the m if we go up a little bit or across a little bit now it goes the other way let's move this guy down and you can see because of the cost of walking through this white and gray tiles it's gone all the way around so that's a path finding it's working we're giving it a start we're giving it an end it's finding the way so that's all we really need for now let's add in a character and make him follow it so the first thing I'm going to do cuz I'm going to go and make a porn I want to stop calling this one node 2D and this one's just going to be our game so that's going to be saved as game make sure that's game so now we're going to go and make a new one so let's go scene new scene and the type is going to be a character body type 2D and the character body type is great cuz it's got a bunch of Milt built-in moving stuff built-in character controller stuff to make it easy to move so going to call this guy a porn he's going to need to have a what's it called a Sprite 2D just to hold his little picture and I've just grabbed a little picture for him so I'm just going to go to texture quick load and I've got this little character sprite here that I like to use this actually an old icon from that's from Golden ax and old SE game so obviously we can't use that in a production game but this is just us marking around this is just our programmer art so I'll put him in for now and when we're going to when we get it if we take this game any further I'll get an artist to come and help me out with that because I cannot draw for now let's add a script to this guy so it's going to be our porn and you see by default it's got a bunch of stuff like his movement speed jump velocity it's got gravity in there so if you're not on the floor we can fall down if you for space bar it'll jump so it's built through like a platforming 2d game so we're not going to use any of this stuff so I'm going to keep this one here cuz what this is if you press the action UI accept which is a space bar then we can do something I'll use that in a minute um this is for moving left and right we're not going to use that but you do want to have a move and slide so that's a built-in part of the character model 2D once we set his velocity it'll apply that when you run this one if you don't have that he's not going to move oh we get rid of the gravity and get rid of the jump velocity but let's keep speed for now and we call this guy a pawn all right and let's go ahead and go back to our game and I'm going to put a pawn in right now oh that's right it needs to have shape so let's go back and let's give him a collision shape 2D and let's make his shape capsule there we go now when we go back to our game and go see a little guy and I want to make sure that he's the size of one of these little squares so you see it's too big right now so what I'm going to do is go back to here and what I'll do is just change the size of this so I think that's right let's go have a look no still a bit too big when I make the final game of course you'd make him the actual right amount of pixels to fit in here oh that's about right I think let's make him a bit smaller little bit too small all right and let's make his Collision shape match all right so what I'm going to do I'm going to tell this guy that when I right click here or left click I think I do left click left click it will talk to the pathfinding class and it'll ask it for a path from here to here then he'll get it back and he'll start walking it first I'm going to make it so I can actually click and it'll find that direction so let's do it first of all I need to actually add that let's go project settings input map and I've already added here so what we do is we add a new action and I'm just going to call it click for now um be a good idea to call it what it is like move or something like that but for now let's just call it click and I can come back later to add that and then we attach that to a button and the button we're going to add it to is a mouse button yeah left Mouse button for now out so that action click is associated with the left Mouse button so now in my porn script when I say is the action pressed click let just print clicked and there we go it's working all right so what we're going to do now is I want to get his position and the way we get that is we go position but there's a problem this will give his position in pixels from here to there so if he's whoops and the problem with that is we want this to be 0 0 this to be one0 but that's actually going to be instead of being one it's going to be 16 cuz every square is 16 pixels wide so we just need to account for that so if he's sort of not exactly in the middle we'll try and round that off so the game thinks he's here cuz the game's path ring is going to work off that grid and all we need to do is just divide his position by 16 but let's make it more programmatic cuz I've got these 16s written everywhere what we can actually do is go to the part in the game where that is defined and that's in the terrain and it's the rendering quadrant size now I haven't got the terain in here yet so let's add that there we go so that will give us its current position and the position we want to go to so that's the target position and we just go get Global Mouse position so that will give us the position here but it won't give it to us from the screen position it'll give us the actual World position so good makes this stuff really easy for us and once again because we want to change it to our coordinate system we're going to divide that by 16 or by the rendering quadrant size and so now we just need access to the path finding and we'll record his path here and so we'll just go path equals path finding request path from his position to the Target position and let's just go and make this method so we've got find path but I don't really like that let's call it request path and then we'll just return that path oops and we're going to change that old one back to here so it will still work in the editor so what it'll do now it'll still get that same path which I need to pass that information through um what do we call it we called it well doesn't matter let's just call it start is a vector 2i and end it's a vector to I so it'll do the same thing now it'll grab that path it'll draw it here on the editor so that we can still see where it's going for now and it return the path to our porn then he's going to know his path and then here's what we do we're going to have his actual walking now and we're just going to if the length of his path is greater than zero so so if there's anything in there right now there's zero in there so he won't try and walk then we need to get the direction to the first point in that path so direction we're going to get the global position and that gives us the global position of our guy no matter where he is it's not going to give us the screen position but the number of pixels from the zero just like our Global Mouse position and we get the direction direction two path number zero so you can see good makes this stuff so easy for us it's ridiculous and velocity is a vector 2 which is what gets past to move and slide to make him move so our velocity is just going to be our Direction and we'll multiply it by his speed and mate that's it all we're going to do now is when he gets to that first point he's just going to stay there so we need to make it so when he gets close to that point we delete it so then he can go to the next one and the way we get the distance is if position. distance to path number zero let's say if it's less than our speed our speed times Delta now the reason we have that is we go our speed is 300 we don't want to go by 300 pixels but what happens is every time this one goes and clicks once it gets divided by this Del or this Del is giving us what it's divided by so basically if we're going 60 * a second that's going to be z uh 0.02 and so this is actually how much of our speed we'll have every tick which is what we want to go for and we just go path we move at position zero so that will move the zeroth position what have I done wrong there whoops that's it so if we get so when we get close it'll remove that position from the path and then the second point will become the zeroth one so then we start walking towards that one and oh one more thing we need to do so our s so if there's nothing left in the path our velocity is going to become Vector 2 0 0 so we're just going to stop all right so we click that'll request the path when we've got a path we're going to walk I think we're good let's try it so little guys there a bit hard to see let me click here we got the path and we can see him walking along this probably hard for you guys to see it's even hard for me to see so let's make this screen a bit bigger project settings General the window size and let's make it 1980 by 1020 I didn't have much let's go Zoom this camera in a bit so there's our guy and my friends we have pathf finding now if we force him to go here you'll see he will do it but he'll always find the quickest way well not the quickest well yeah sort of the quickest way but he'll calculate and you see he'll always go around those big mountains if he can all right while we're here why don't we actually change his speed as he walks over this lens so it does actually cause some cost all we need to do that is go back to our porn and here when we're doing his velocity I'm just going to multiply that by path whoops finding. get terrain difficulty so that's that's a little method we made here which will get the walk difficulty of the position and we're going to get the walk difficulty of the position Underneath Him and the way we do that is we just grow position divide by terrain do rendering quadrant size so get out 16 and we're actually going to not put in the number directly we're going to divide that number by one in fact that's getting really long why don't we grab this massive thing here there we go so if the could is one that's 1 divide by 1 it'll be 1 or if it's two it'll be 1/ by 2 that would be 0.5 so now we'll be dividing his speed by a half or multiplying it by a half and let's see how that works so walking across the green is pretty quick dark's still pretty good but you'll see as we get into these darker ones he starts to walk quite slow and you can see on the snow he walks super slow there we go so now it actually means something that's a reason for him to walk around and find the best the best path because it does actually cost him to walk on the higher land although more difficult to walk land okay so before we finish up I was going to show you how to add in objects like trees and rocks in another layer and have that work with the pathf finding as well but we've been running a bit along so what I'll do is I'll just quickly show you how to make something completely impossible and we'll do it for this white snowy areas so what you do is you go back to your tile set and you grab the one you want and we're going to set the custom data and I'm going to make um let's make it minus one and minus one will be my little signifier that is impassible so we'll go back to our scripts and if you recall I've got this little script here which sets a point to solid which makes basically the path finding will ignore it all together if Terrain dot sorry not terrain if get to rain difficulty of Vector 2 i x y equals minus1 now I'll put in way too many parentheses here let's fix that up oh the parenthesis yeah then what we'll do is we'll set that position to be solid or else we'll treat it as normal what have I done wrong oops all right so if the terrain difficulty is minus one we'll set that point solid Let's test it out so now you can see when we walk I can't even click on this area at all it's not part of the pathf finding at all anymore and even if I take let's let's try and walk from here to here something that we should definitely take a path through there it's going to walk all the way around because simply those squares are not included in the pathf finding and you see we've got a little bug there as well and that is caused if you look closely you can see we're actually not drawing lines to the middles of squares let me zoom in and show you what I mean we're actually always drawing our lines to those top left Corners um now that's actually a bug because we want to treat the middle of the square our Square so let's quickly fix that it's really easy all we need to do is after we generate our path we're going to Loop through that path before I in range length of our path path I we're just going to add to it Vector two and basically we're going to add half of a square to it now let's do this the programmatic way let's go terrain dot terrain do what was it rendering quadrant size and of course divide by two so we're getting halfway through those squares let's give that a try and there you go now we're going to the middle of our squares all right guys I think that's enough for today we' got our little guys running around now um now of course once we've got that it doesn't have to be us manually clicking him telling him to move somewhere it's going to be a rim World style game so the character will have his own little needs and want and and little priorities and so when he thinks he wants to go eat some food he'll find some food on the map and if there's food over here he'll go and just find his way to it so this is a big badrock of our game here and now that we've got it we can go and build from there all right thanks guys I've taking enough of your time for today have a good one I'll see you next time
Info
Channel: Real Robots
Views: 3,716
Rating: undefined out of 5
Keywords: godot, godot 4, gamedev, how to, programming, coding, pathfinding, pawns, rimworld, character controller, colony management, sim, astar2d, astargrid2d, tutorial
Id: PIPlWCyHf7s
Channel Id: undefined
Length: 37min 17sec (2237 seconds)
Published: Wed May 01 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.