Make a 3D Top Down Shooter with Godot - Part 1. Character Controller

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to the age of asparagus if you haven't seen the intro to this tutorial series you should go check it out to get some context for the project and see an example of the game we'll be making by the end of this episode you should have a little character that moves around and tracks the mouse cursor's position in the level all right let's give this a go look at this i got good oh open that's like i've never used it before so i'm going to cancel this we're going to start a new project let's pick a better place than this so i'm going to go into my documents folder and i already made this here because i'm tracking the files on github and i'll be posting them there so you pick your own spot here i'm also gonna create a folder let's just call it 3d game okay you can probably be more creative than that and i'm gonna call the project 3d game as well oh that little d there that's annoying 3d game and we'll use opengl es3 i'm going to full screen here with shift f11 and you might notice my editor is a little bit larger than normal that is because i have gone to the editor settings and increased the display scale to 125 just to make it easier for you to follow along sometimes it's hard to read code on youtube it's a little small to text there so let's add a 3d scene and i'm going to double click this and call it my level we'll add a ground and hit the plus there and we're going to type csg so a csg is a constructive solid geometry and it's just a bunch of different kinds of meshes you can join together you can cut one mesh out from the other mesh and it's really nice for rapidly prototyping levels it also comes with a built-in collision which is really nice you don't have to add an extra node for that so let's start with that these csg meshes have these little pink dots here which you can use to resize and quickly build up your level i'm going to undo that with some control zeds whoopsie ctrl shift zed will redo to get me back here before i resize it i'm going to go up to this icon and use snap with the little magnet there and now when i move it it'll snap to the grid so i'm going to zoom out with my scroll wheel and orbit around by clicking my middle mouse button and holding it and moving my mouse so let's pull this out about 10 units one two three four five six seven eight nine ten and we'll do the same thing over here ten good and if you want a flat plane you could do that bring it down one but i'm just gonna leave mine thick i'm also going to move it down one so that the top of the plane lines lies flush with our nice grid there and that looks good i'm going to hit the plus here and we're going to look for a kinematic body if i type body here we've got three kinds of bodies we can create a static body is an object in your game that doesn't move but still interacts that would make a good floor or other objects that you might run into a rigid body is something that would be interactive but affected by physics like gravity and friction and stuff and a kinematic body is something that will interact with objects but in order for it to move around you need to script it and that's what we want as you can tell by that handy little playery-like icon if you accidentally created it and it's underneath your csg box make sure you grab it and put it directly underneath your level so that it is on the same indentation level as the csg box why don't we double click that csg box and we'll call it ground and we'll double click the kinematic body and call it player now there is no player there is nothing there so let's with the player selected i'm going to right click it and add a child node and this time we're gonna add a mesh instance now remember since we're working in 3d now you want to stick with the pink nodes there are corresponding 2d nodes which will all show up in this bluishy color here so we have a mesh which still doesn't look like anything because in the inspector here under mesh let's click empty and choose a new capsule mesh there it is floating on top of our level it is dead let's stand it up by rotating it with the red circle that's rotating on the x-axis and you'll notice down here in the corner as i rotate it it is rotating in 15 degree increments because i have my snap turned on so we want it to be up and down 90 degrees there that's good you can confirm that by going over here clicking the transform and just making sure x is at 90 degrees okay now i could move the capsule up but i don't want to because then it will get disconnected from my player here so let's undo that movement and i'm going to select the player and turn on this buddy so that we cannot accidentally select the mesh and move it when we move it it will move both the player and all of its children so we'll move it down and i'm orbiting around again we pro zooming in let's turn off snap temporarily and we'll just get it close it can float a little bit that's okay and i'm going to turn snap back on just in case we want it later let's add a material to the player so let's select the mesh instance and then we are going to over here in the inspector expand the material section click empty and we're going to do a new spatial material click the bali white bali thing that shows up and this will let us edit all the properties in godot the albedo is what parameter that affects the color here so let's click on the color and i'm going to choose a hue already hue plummy ready hue something like that sure okay and i'm going to click away and there we got it the ground appears bluey well it appears extra blue when i select it because the selected csg objects get extra blue if there are other ones they wouldn't be like this but it's still even blue when it's not selected and that is because of our sky so maybe we should add a light let's add a light select the level and right click add a child node let's see what light options we have here we'll go with uh let's go with a directional light that's a sunlight that has a direction but it doesn't matter where the sun is where the light is the effect will be the same so let's just move it up from the middle and we'll get it out of the way a little bit over here and if i orbit around you should see an arrow there's the arrow so the light is pointing that way and you can see the light coming from this direction and hitting it so if i rotated this a little bit you'll see that the light changes where it's coming from now it's facing that way now the light is coming from the other direction okay let's just have the light coming from about there and we want some shadows to appear on the ground here so with the light selected over in the inspector i'm going to expand the shadow section and tick enabled but i cannot see any shadows and that is because the light is coming exactly parallel and there is no light to cause a shadow so we need to rotate it down a little bit so i'm going to rotate it and there's our shadow you can just play around with the rotation until you get uh the shadow lighty thing that you like i'm just that looks good to me so let's stick with that i also notice the light is now hitting our ground plane so it looks a little lighter as well so we have a player and level and let's get it moving around so with the player selected i'm going to click this attach a new script button and we'll call it player it's just going to create it in the root of our game which is messy and not a good practice but we'll clean it up later if we need to if the project gets big enough but for just this this little thing it might be fine okay we can get rid of this and we'll use the process function i'm going to select these two and if i hit ctrl k that will allow me to unblock a comment and if i highlight a whole bunch i can hit ctrl k here and toggle big sections of comment that's really helpful get rid of paths so in our process function we're going to get the user's input and then move and slide our character just like in 2d so let's create a couple variables we'll have some speed for our character and we'll have a velocity which will be a vector three we need even though we're only going to be moving in two directions we need to use a vector three for our kinematic body which is expecting a vector three for its movement slide and maybe later on we'll get it we can add some jumping or something okay so in the process function we're going to reset the velocity each time this function runs every frame to an empty vector and let's get some input so if input make sure you got a capital i there dot is action pressed and you do not want just pressed you want pressed if you just pressed it'll only trigger one time even if you click and hold it down so action pressed will cover us for clicking and holding and we're going to use some built-in actions let's use ui right good and make sure these are all lower case it should auto complete which will prevent you from adding any typos colon and so if we're going to go right let's do velocity.x and we'll add 1 to it plus equals 1. so we're going to do this for all four directions that's annoying by the way if i paste and it's tabbed in i can highlight both lines and if i hit shift tab that will indent all the whole highlighted section let's get you back over there and final one here boom okay we're going to have change this to left good up and down so for left we'll have x is minus 1. for up we're now going to use zed and up plus one sounds logical and z minus one for down i don't know if that will work let's check it out and make sure we got those directions correct uh we also need to move the character so let's go move and slide with our velocity whatever that is at that time all right wow we haven't even saved our project yet that's not smart we should be saving our project all the time so um left hand should be on control s and you should form a habit of hitting it regularly ctrl s okay so let's save this level scene we can just save it as level again we'll save it just here in the root like bad disorganized game designers probably and we'll save our scene everything's good okay we have a move and slide velocity let's see if we set this up properly i'm going to play the scene and what gray we have no camera with which to view our level camera time so select level let's right click it and add a child node what cameras do we have available to us we're just going to do the base camera and like everything it's going to show up here at the origin let's move with the camera selected let's move it up snapping nicely and we'll move it back i can see the camera if i look in here if i hold shift and middle click i can drag up and down i can pan i can see it's facing that way so let's grab it in the z direction and move it back a little bit what does that look like what happens if we play it now yay but that's not what i want the camera to look like so let's um let's go to view here and we'll do two side-by-side viewports and with the camera selected we can click this preview button here and that will show us what the camera is looking at so now as we adjust and move the camera we can see what the game is going to look like okay that's good i'm moving it up i'm just going to zoom out a little bit here and zoom up and let's rotate it on the x-axis here with this red ring look down a little bit yeah it's looking good but we want to be further away okay up i can also grab this little red square here which will move it in the in the plane that i want and i want it to look down something like that yeah that looks fine all right let's go back into our single viewport now we can hit play there's our level and if i use the arrow keys i'm moving very slowly and badly and also okay my left and right is working but my up and down is backwards so let's go fix that that's easy we'll go back to our player script and we'll switch the z's from negative z and positive z how's that that'll work right yep all right so we want to move faster than that so instead of passing the velocity let's update it here so we'll set the velocity equal to itself times the speed we created and i set it at five you can change that to whatever you want and that new velocity multiplied by speed we will be moving in okay how about that yeah it's a decent movement maybe we could go a little faster if we wanted but one thing you'll notice is if i go down and up i have a certain speed and left and right a certain speed but then if i press up and to the left i actually go a little bit faster here and that's because we haven't normalized our velocity before we multiply it by the speed so we want the velocity at this point just to be a direction in fact it might make sense to call this direction until we multiply it by the speed but we're good now so let's just go velocity dot and we should be able to just grab the normalized velocity so that's basically just a direction it's a vector with a length of one and then we'll multiply it by the speed and now when we move around that's a little more natural and it's pretty slow so maybe maybe we can make it to like eight or something i don't know we'll probably be tweaking this a lot later but oh yeah that's better okay so the next thing we want to do is we want the character to be able to turn and look at wherever my mouse is pointing on this plane here so it's just a capsule that's going to be hard to see so why don't we give them some little goggles or something let's zoom back in here and under the player we're going to add another child node let's add another mesh another mesh instance and this time let's call it uh sorry over in the inspector the mesh we'll give it a let's do a cube mesh and under expand material here we'll do a new spatial material click the the sphere and under albedo let's change this to uh let's do like blacky charcoaly black just because it'll look i don't know he's wearing shades so because i have this turned on children are not selectable i accidentally select it away and back again i can't actually select the mesh instance so i got to select them in the scene tree and let's turn on the let's go to the scale widget and this is going to snap which is going to not oh is snap off not sure it's not snapping though so that's fine with me let's just adjust this uh to look like something interesting oh it's going through both so let's squish it out and move it boom move it up a little bit boom yeah here we go let's turn off snap uh cool so he's he's looking in a direction now okay i'm going to double click mesh instance 2 here and call it eyes and maybe i'll double click the first and call it body just to make them easier to reference if we need them okay so now we somehow need to script it to follow and turn and follow the mouse so this is a little complicated and it's going to be using rays and stuff okay so here's how we're going to do this imagine this is our 3d world and this here is the screen that we're looking through to play our game this rectangle here will match the rectangle here on the front of the camera and you can imagine if we had a mouse pointer a cursor on the screen that it would have an equivalent position on our camera in 3d space right here which would be a vector 2 on our screen with an x and y coordinate so the point we want to get if we're pointing on our screen right there our ground which would be somewhere over here in 3d space so somehow we need to find the 3d coordinate the vector 3 of that point from just this mouse cursor on the screen and how we can do that is if we have the origin of our camera and then if we could get a vector that went from the origin of our camera and through or to where our mouse cursor is positioned on the front of the camera something like this a vector pointing out in that direction or if our mouse cursor was over here in the top corner which might be somewhere up here in 3d space we the vector would be pointing off in a different direction at least that's the way it would be for a perspective camera the calculations would be different if we had an orthogonal camera and one of the reasons why the code i'm going to write in a moment here is more complicated than it needs to be just to find the camera origin is because that takes into account if you were using an orthogonal camera as well but for now we're just going to worry about the perspective camera because that's what our game is using so far anyway then if we could take this vector and multiply it by a large number so that it extends off into [Music] a long ways away much further than we need out here somewhere way off in 3d space we can project a ray from an origin point off to some target point which is basically like a laser beam and the special thing about rays in game engines is that they can detect collisions with shapes that have collision detection in your 3d world so in our case as long as the ground plane has some sort of collision ability then the ray will be able to detect where it collides with the surface of our ground which should be the point that our pointer is looking at if we were looking it through the camera and then using that we could turn our player to face that collision point so the hardest part of this is how do we get a vector that goes from the origin of the camera and points through the cursor's position in 3d space on the front of the camera well thankfully godot has a built-in method that will give us this vector based on where the mouse cursor is on that screen let's do this in our level we'll have our level be the kind of the boss and controlling everything so i'm going to add a new script for our level and i'm going to call it main and in the main script we can get rid of all the bottom stuff here we're going to use the physics process we have to use the physics process because there is a method we're going to use that only works within the physics process some information we need that is only available here we're going to need to get two points we're going to need to get a start point and an endpoint so i'm going to create a variable called ray origin which is going to basically be where the camera is and from the camera we're going to look at we're going to go to some target point and that target point which is a vector 3 as well so in the physics process we're going to get the mouse position so we'll create a new variable called mouse position and get viewport method we can get the most position there it is okay so what is that exactly well one thing i'd suggest you do when you're not sure what's going on especially what this means like mouse position how in 3d space well it doesn't really make sense to say that so we can debug this and how i often do this is just print we'll just say mouse position like the name of the variable basically with a colon and a space comma and then the variable and then run it and we should be able to see what's happening so mouse position is zero zero so when i'm outside the game it's not registering anything and there's the most position so you can see in the top left is basically 0 0 and then the y value goes up as i go down and then the x value goes up so you can see this is screen coordinates in probably pixels so i'm going to control k that to comment it out so we're going to set the ray origin variable and equals we're going to use that magical dollar sign to get other child nodes of our our level script let's get the camera and we are going to call project ray origin based on the mouse position variable here what is this doing this is probably the most confusing one i'm not really sure but the camera doesn't move so i suspect that the origin should always be the same let's do that and that well that's a complicated way of getting the camera's position ctrl k that let's tab in there and now we need to get the ray target so these are these are points in 3d space they're vector threes so i should say target we're going to start at the ray origin which is the camera's position in 3d space and then we're going to go in the direction from the camera so we'll start the camera and we'll go we'll project a ray normal this is going to point from the camera to the mouse position and we want it to go a long way so let's times it by a thousand because i am zoomed in quite a bit i'm just going to shrink this section here so that i have a little more room for my code so here's where we got to use some a little bit of magic here so we're going to create a new variable called space state and we're going to get the world what does get world do get world can get us information about the physics of our world and we're going to do something called we're going to get the direct space state why what does that mean well because we can use that to find things in our world that are intersecting with our ray that we're going to create okay so let's use this space state whatever that magical thing is and we're going to check to see what this ray intersects with so we're going to intersect array arrays just like a line the line is going to go from the ray origin which is the camera to the ray target which is looking from the camera to the mouse cursor and it just keeps going on for a long ways and so as that line shoots out from our camera towards the mouse pointer in 3d space it's going to interact with stuff and this intersection is going to be a dictionary with a bunch of stuff in it and we need one of those things but first let's make sure we're actually intersecting with anything so we're going to go if not intersection empty intersection dot empty so this checks if the dictionary if a dictionary is empty and we want to make sure it's not empty if it's not empty then let's find where the position of the intersection so we're going to go var we'll just create a variable called pause for position equals inter section and it's got a whole bunch of information in intersection but the one thing we want is the position of the intersection where that ray shooting out from the camera actually hits the last thing we need to do is turn the player so that it looks at the mouse pointer okay so we're gonna use the dollar e dollar magic again and this time we're going to use the player node and use that beautiful look at where are we going to look at well we're going to look at the position that we've discovered which is the position our mouse touches that plane and look at needs a second value which is the up vector so in this case i can just do vector 3 dot up because we're just using the default up we have the gravity is not acting upside down and weird things aren't happening so for now we can just let's just do vector3 dot that works and now we should have some lovin we do not why not let's debug that okay so are we even getting in here is the intersection empty let's find out print not empty okay there is nothing here okay um we're not actually colliding and that's because i did not turn on collision with our csg um instead of creating a collision shape here we can just go to the ground and where are you here use collision let's turn you on and see what happens hey look he's looking oddly okay uh and not empty good so we have a collision and it clearly our player is following it although it looks like he's trying to listen to the pointer really carefully maybe we can shoot lasers out of his ears or something so this is caused because what the look at method does if we go to our script we can uh here's look at so let's search help and go look at we want the 3d spatial one and you'll see that it rotates itself so that the location the local negative z-axis points toward the target position okay so for some reason our negative z-axis is coming out of its ear our player's ear which there it is right there look so the positive z-axis is this blue one and by the way uh just a trick to help remember what all these colors do i always remember rgb you know like the rgb colors red green blue well that's xyz so red x green y blue z rgb xyz okay the positive z axis is coming out of this here the negative z axis is coming out of his other ear so let's rotate the player what we want is we want the player to be looking in the negative z direction because that's what that look at method does for us so over in the inspector with the player selected i'm going to go into the transform and there's no rotation so let's rotate the player snap on i'm just going to turn snap on here and rotate the player to look in there negative z direction away from the blue arrow and what happens now if we try it what he's still listening okay that didn't work let's not rotate the player instead let's rotate the body because we're using the player for stuff and by transforming it's going to cause us problems so let's just rotate the body mesh um to face that direction of course the body mesh does nothing because it's a symmetrical capsule undo that let's take the eyes because the eyes are on the body so they should be a child of the body actually so now when we rotate the body the eyes will rotate with it there we go so now the eyes are facing the negatives that direction how about now hey it works we obviously have one small problem still and that is this player is really intent on looking at this arrow even right down to the ground so although we want it to look at the arrow we want to look at it to look at the arrow as if it was kind of eye height for the player we need to change the y value of where it's looking at let's go back to the level script here and where we say look at this position um let's create a new variable called look at me and it will be a new vector3 and we want to use the same x position and the same z position pause dot z but for the y position we just want to use the player's own y position right because we want it to kind of look at its height or at least somewhere up there so let's go get the player again with the magic dollar sign player dot and we want its translation and we want its y translation okay so now instead of looking at the intersecting position we're going to look at this new point called look at me which is just the intersection position but moved up by the same height as the player hey cool eh it's working all right so in the next video we will get rid of this not empty um let's do that now not empty i just control k out all these comments because in future debugging it becomes really easy just to add some of these things back in all right so in the next video we're going to add some weapon mechanics and stuff uh carry on hopefully i don't know what to say don't forget to save your work ctrl s save it all save often you
Info
Channel: Age of Asparagus
Views: 7,118
Rating: undefined out of 5
Keywords: AgeOfAsparagus, Godot, Tutorial
Id: HX6qpYjwN3M
Channel Id: undefined
Length: 30min 22sec (1822 seconds)
Published: Sun Feb 28 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.