[Unity C#] First Person Controller (E01: Basic FPS Controller and Jumping)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello its acacia developer here and today I'm going to be talking about creating an FPS player which can jump so by the end of this video you should be able to create an FPS controller that can jump will be implementing the camera controls the movement and of course the jumping feature as well so I want to start by creating the FPS player in the scene I'm going to create an empty game object and then attach a character controller to the empty game object like so and then I'm going to rename that to player now this represents the player's body or the collider for the player if you like and then as a child I'm going to create a camera game object and I'm going to rename this to player camera this is going to be the camera that we view the world from I'm just going to shift it up 0.9 units on the y-axis and that way if you have a character controller that has a height of two units your camera should be just peeking out the top of the capsule shape that represents our character controller which is exactly what we want now you may be wondering why I've chosen point nine and not one like so and that's because later on when the character controller is jumping if we don't push the camera down by point one units on the y-axis then it actually Clips through the ceiling so just a heads up as to wild chosen point nine so now let's create our scripts that we need the first one is going to be player look and the second one is going to be called player move now what you want to do is select your player body I'm going to attach our player move to that and then select our camera and then attach our player look script to the camera let's access the player look script to begin with in the player look class we want two strings that store the names for the incoming inputs for the mouse X and mouse y-axis so we can declare these strings now I'm going to pull the first one mouse X input name and the second one Mouse Y input name like so now below that we want another field this is going to store the value of our mouse sensitivity and this is a float and then below that I'm going to declare a private function called lock cursor and we're going to call this function whenever we want to lock the cursor to the center of the screen and to do that we'll simply assign our cursor o'clock state with cursor lock mode locked and that simply confines the cursor to the center of the screen and of course we want to do that when the level first loads so we'll call the lock cursor from awake now down here what I want to do is declare an update function and then from the update function I want to call another function called camera rotation like so I'll just call that from here so in the camera rotation function I want to get the input of the mouse on the x axis and to do this I'm going to declare a local float variable called Mouse X and I'll go in to assign this with input.getaxis now we want to get the value of the mouse on the x axis so we pass in the name which is stored in our mouse X input name string and then we factor in our mouse sensitivity as a multiplier like so and then we multiply again by time.deltatime now we do something very similar to get the y axis for the mouse just need to change a few names so now we want to rotate the camera we simply grab hold of the cameras transform and we call a rotate function and in here we can actually pass in the vector 3 which is the amount that we want to rotate the camera in this case is going to be the negative of transform right and we're going to multiply that by our mouse Y so back in the unity editor I'm going to set my mouse sensitivity to 150 because that's a nice value in order to obtain the names for the mouse X&Y input you can navigate to edit project settings and then if you click on input you open up the input manager and as you can see I've already extended these out but you can see the names of mouse X and mouse Y these are the strings for the names and simply we can insert mouse X and mouse Y into the string slots here like so and then our player looks script will be able to find the appropriate input associated with these strings which will be our mouse x and y inputs when we press play we're only going to be able to pitch the camera because that's what we told the code to do by the moment one big issue that I want to fix is the fact that if we look all the way up and keep looking further we actually flip upside down and the same when we look all the way down and keep going will flip upside down so what we want is a method of clamping the camera so we're only able to look 90 degrees up and 90 degrees down and no further so because of the conversions between Euler and quaternion representation of rotations it's difficult to clamp rotation axes directly so in this case we're using an external variable to keep track of the amount of rotation that we've added and subtracted to our camera and then we're using this value to clamp instead of using the x axis rotation directly to clamp so back in our player look script what we want to do is factor in a new variable and this variable is going to be of flow datatype and called x-axis clamp and initially we want to set that success clamp to zero in order to pitch the camera we're using the mouse Y input so what we can do is add our most Y onto our x-axis clamp like so so x-axis clamp is going to be keeping a constant record of the amount of rotation that we're applying to our camera whether it's positive or negative so if you think about it if the x-axis clamp is equal to then we know that we're looking directly upward but if x-axis clamp is equal to negative 90 then we know that we're looking directly downward for now I'm just going to hard-code these values but I'm going to add an F so if the x-axis clamp is larger than 90 then we know that we are looking directly upward so we clamp our x-axis to 90 so we keep it at 90 but then we set our mouse y-value to 0 now this is very important because you see down here that this rotate function uses mouse Y so by making this 0 we're essentially applying a rotation of 0 now I'm just going to copy and paste this below because it's rather similar but in this case there's going to be an else F and if our x-axis clamp is less than negative 90 then we want to clamp clamp it to negative 90 and the mouse Y will still set to 0 so as long as the X rotation for the camera is 0 initially and the x axis clamp value you make sure to initialize that to 0 then this should work but you'll find that the camera is still able to slightly overshoot the clamp so what we want to do is directly clamp the x axis to a specific value and I'll just declare a function down here to do that I'm just going to call this clamp x axis rotation to value like so and I'm going to pass in I'm gonna have someone pass in a float value and what we're going to do is we're going to get the Euler rotation of the camera so we'll access the transform boiler angles and then all we want to do is set our x axis rotation to the value that we've passed in and then we'll set our rotation back to our oiler rotation value like so and now what we can do is up here we can call our clamp x axis rotation devalue and believe it or not when the camera is looking directly upward we're actually at 270 degrees and down here we're going to be facing 90 degrees when we're looking directly downward so really this function just stops the camera rotation exceeding the clamp which can be a serious bug and as you can see the camera is now clamped correctly and we can't look any further and flip upside down so now that we've got the camera pitching up and down on the x-axis we now want to implement some horizontal rotation relative to our camera so in order to do this we continue to pitch the camera up and down on the x-axis but the player body is the object that we're going to rotate on the y-axis and since the camera is attached to the player body that means it will move with the player bodies rotation as well so back in the player look script we want a field that stores a reference to our player bodies transform I'll just call this player body we can now access our player body transform and then we can rotate that on the appropriate axis using our horizontal mouse input so in this case it's going to be vector three up and then I'm going to multiply that by my mouse X we'll also need to change this negative of transform right to vector three left or else you'll get some very funny rotations with your camera and now back in the unity editor you'll see a slot for the player body and you can simply drag in our parent game object from the hierarchy drag that straight into the slot but now when we play the game as you can see we can look down we can look up and we can also spin around to look at our environment so we're now going to implement movement so we're able to walk forward backwards left and right so as you can see in the scene view with the player body selected the blue arrow is always pointing out the front of the character controller which is where our cameras facing and the right arrow is always pointing out to the right of wherever the camera is facing the blue arrow is called the transforms forward vector and the red arrow is the transforms right vector so what we can do when you press the W or the up key we can instruct our program to move in the direction that the blue arrow is facing which is our forward vector and then when we press our a and D keys to walk left or right we can actually use the red arrow or the right vector so this is a visual representation of the vertical axis it returns a value between negative and positive one when neither W or s oppressed the value is zero but when W is pressed the value increases to 1 and when s is pressed the value decreases to negative 1 so by multiplying the value by this axis by the forward vector if we press W we're multiplying the forward vector by 1 and therefore we're saying move in the direction of the forward vector one unit on the flip side when we press s the value becomes negative one and by multiplying the forward vector by negative one that gives us a vector that points in the opposite direction of the forward vector and this is the direction that we want to move in to move backwards the horizontal axis works exactly the same but for the A and D Keys instead so now in the player move class we want a couple of strings that store the names for the horizontal and vertical input this covers the up and down left and right arrow keys the WASD keys and the arrow keys on your number pad I think but essentially it's very similar to what we were doing before with the mouse and y-axis except in this case we're going to call this horizontal input name so this is going to be for our left and right arrow keys or our a and D keys and then we want another one I'm going to declare this one on another line and this is going to be called vertical input name and this is going to be for your up and down keys or your WS keys another thing we want is a reference to our character controller I'll just call this child controller for now and then since this is the actual player body that this script is attached to we can actually access our character controller directly what we want is we want to store a reference to it in our child controller field but we can access it directly through getcomponent and now what we want is an update function and we want a player movement function which will handle all of our character control this movement and we'll call this from the update function so like before with the mouse X and mouse why we want a local variable that gets the input input get access and in this case we want to pass in our vertical input name and then I wants a multiplier so I pair or declare floats which will be our movement speed and they'll multiply that by movement speed and then time.deltatime like so then we just want one for the horizontal input which is very similar except I'll just pass in our horizontal stream instead and now what we want to do is specify the movement the direction that we're moving in and the amount that we're going to move in so in this case we're going to declare a vector3 and call this forward movement and this is going to be equal to our forward vector so the forward vector of the player body x whatever we have for our vertical input and then we have our right movements and this is kind of our movement to the side when we press the a and D keys then we want to move along transform right x our horizontal input like so and now we actually want to move our character controller using these values so we can simply type chart controller dot simple move and then within some of the simple move function we can pass in our forward movement plus our right movement like so so basically I've just added these together so I can actually pass both of these in using a single function call now up here you'll see that I've mistakingly x time Delta time but we don't actually need to do that because simple move actually applies time.deltatime under the hood for you so back in the unity editor if we select the parent of our camera object you'll see our horizontal and vertical input names the movement speed for now I'm just going to put at 6 in the horizontal input name box I'm going to tap horizontal because this is the name of that input I know this but you can check yourself in the input manager so horizontal and vertical so as you can see for the first time our playercontroller has just fallen to the floor and hit the floor we can still look around but now if we press W or s we can move forward and backward and a in deflecting right we can also use the arrow keys and I believe you can use the arrow keys on your number pad as well when number lock is off but but yes this definitely works now so now back in the player move class what I want to do is implement jumping so first of all we're going to need a private field which is of boolean data type and this is going to dictate whether or not we're jumping in the air and on top of this we'll also want some fields that we can access in the inspector and this is going to be an animation curve and I'm just going to call this jump fall off so we're actually going to be using an animation curve to specify how we jump and then I'm going to declare another field and this is simply a float and this will be our multiplier for that curve we also want to specify a key code and this will be the key that we use to jump I'll just call that jump key so now what I'm going to do is create another function called jump input and this is where we're going to handle our jump input and we also need a function that returns ienumerator it has to be iron emerita because we're using this as a Co routine and I'm just going to call this a jump event so and for now I'm just going to yield return null so we don't get any red squigglies and also don't forget to call the jump input function from the player movement function so in our jump input function we want to check whether we've pressed Aki so if get key down jump key where's our chunky yeah and if we're not jumping and then what we want to do is set is jumping to equal to true because in this case with press space and we're now jumping and then we want to start our KO routine which is our jump events so within our jump event we're actually going to use a do-while loop so we'll have our do here and then our while condition down here and then we want I yield return null to be within our do block before our while loop we want a float variable that keeps track of the time that we've been in the air and initially we want to set that to zero then in here we can specify another flow and this is going to be our jump force and this is going to be equal to our jump fall off so remember that's our animation curve and we're going to evaluate it at a certain point and we're going to pass in our time in the air so now what we want to do is cool our charge controller dot move function so instead of simple move this time we're calling move and the move function is used for more complex movements such as jumping so in this case we want to move in the upwards direction which is vector3 up we want to multiply that by our jump horse then we want to multiply that by our jump multiplier and since the move function doesn't apply time.deltatime under the hood we're gonna have to do that manually and this expression so time knocked out a time like so and then of course we actually want to increment our time in the air with our time.deltatime so basically this will add a single second into our time in the air and then below I want to specify a while condition so while the character controller is not grounded so if we're not grounded and we want to make sure that the char controller dot Coalition Flags is not equal to collision flags dot above and basically what this does imagine the player jumping in a place with a very low ceiling as soon as the player hits the ceiling we want to stop moving upward and we want to fall back down and by appending this to this condition we can do that and then any code after this loop we know that the jump event has just finished and in this case we just want to set I is jumping value back to false again so back in the unity editor we now have our new fields that have appeared in the inspector and I'm going to set my jump key to space so I'm just going to search for space like so the jump multiplier for now I'm going to set that to 10 and now we can actually specify our curve for the jump fall off so when you first open it you'll see a blank graph but there's a few presets down here that you can select usually I like this sort of curve or possibly this one and then I take this key at the front I'm going to drag up to the top left-hand corner I'm gonna take this latter one and move it down here and then you can also see that you can manipulate these handles to change the direction of the curve so this point up here represents when the player initially jumps and you'll find that the longer that we're in the air the less and less upward force is applied to the character controller until we apply no new force and probably at some point around here the character controller begins to fall back to the ground again and then usually I like to drag this key to around 0.7 and this sort of curve gives you a nice jumping animation so now within the game when we press space as you can see the player can jump up and down there is one problem that I would like to address and it's when the player is right up against a surface like this and walking forward when you try to jump you'll get the strange sort of jitter from the character controller if you back up and jump then you'll be fine but it's only when you jump up like this back in the player move class in our ienumerator jump event what we can do is we can set the character control the slope so chart controller dot slope limit what we want to do is when we begin jumping we want to set this to a value of 90 but then when we finish jumping we want to set it back to its default value again which I think was 45 and as you can see when we jump we're now able to get up onto the boxes without the strange jitter and likewise for these platforms as well now before the video ends I just want to address one more problem and that's the problem of the camera clipping through the ceiling so you may have remembered from earlier that we made the camera 0.9 units high and it's because of this so when we jump you can see that the camera Clips through the ceiling and we can see through to the other side now in order to stop this we have already set our camera to 0.9 units on the y-axis so all we need to do is go to the camera component navigate to the creping planes and you'll want to make the near clipping plane 0.1 and as you can see when we now jump the camera no long klipsch through the geometry that makes up the ceiling thank you very much for watching this tutorial of course if you found it useful feel free to like and subscribe and like always I shall see you soon
Info
Channel: Acacia Developer
Views: 166,956
Rating: undefined out of 5
Keywords: FPS Player, First Person Controller, Unity FPS Player, Unity First Person Controller, First Person Controller Jumping, First person controller, Unity, Unity3D FPS, Unity FPS, Unity first person controller
Id: n-KX8AeGK7E
Channel Id: undefined
Length: 24min 13sec (1453 seconds)
Published: Tue Jul 31 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.