FPS Controller with Unity's New Input System

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to another unity tutorial in this video we will learn how to make a first person controller using unity's new input system covering horizontal movement custom gravity and jumping to a desired height if this video helps you remember to smash like and subscribe and without further ado let's get started i have opened a blank 3d project and not done anything to it yet the new input system is not included in project by default so to use it we will have to go to the package manager from window package manager give it a moment to load and then search for input select the input system and then at the bottom select install if you have not downloaded this package before the button will say download instead once it finishes installing we will be asked if we want to change the default input handling from using the old input system to the new input system we do so click yes and then wait for the editor to restart once the editor opens up you may see this error here telling us that the 32-bit version of windows is not supported by the input system i believe that it is safe to ignore it as i have never had any problems doing so before but if you want to make it go away simply go to file build settings and set the architecture to 86 underscore 64 and that will solve the problem just to prove that it works without doing this i will leave it as the default settings now in the hierarchy i can right click and create a new plane i will call this ground then set its scale on the x and z both to three i'll also reset its transform position next i'll click on the layers drop down and select add layer in the next empty slot i'll add a grind layer and then go to our ground object and assign the layer next we will be creating the player but before we do so i think it would be beneficial to talk about the different types of controllers you can make there are two main ways to make a player controller in unity a physics-based approach using a rigid body and a non-physics-based approach using a character controller each of them have their own advantages some of which are on the screen now and which one you choose ultimately depends on what type of game you are making for example if your game has lots of interactions with other physics objects a rigid body would work well but if you don't have many physics interactions and have lots of slopes and stairs a character controller would probably suit your game better with that in mind we will use a character controller for this tutorial as it is smooth customizable and a great all-around controller that works pretty much out of the box with that in mind i will create an empty object and call this player i'll reset its transform then add a component to it which will be the character controller if i now turn on the gizmos in the scene view select our player then hit f to focus on it you'll see a green outline showing the boundaries of our player i will set its height to 3 radius to 0.6 just to make it a little bit bigger and then its center on the y to 1.5 so that it stands on the ground now if i right click on the player i can add a capsule component which allows us to see it we can remove the collider since the character controller deals with all collisions and set its scale to 1.2 on x and z and 1.5 on the y i will also set its position on the y axis to 1.5 so that it stands on the ground finally parent the main camera to the player by dragging and dropping it on reset its transform and then drag it up on the y to approximately where the eyes of a player would be with the game objects all in place let's create a new folder so right click in assets create folder and i'll call this player inside of this i will create a new input actions which we got from the input system package and call this player controls make sure to check generate c-sharp class and then click on edit asset this window may look confusing at first but it is really quite simple on the far left we have action maps these are just large containers in which we can store actions actions are defined in the middle and are simply input from the player such as holding down w or pressing space on the right you can see the properties of different actions allowing us to customize them with dead zones double taps and other cool stuff to see that in action create a new action map and call it ground movement select the default action and i'll hit f2 to rename it and i'll call this horizontal movement then say its action type to pass through meaning to continuously listen for input as opposed to a one-time press and then its control type to a vector2 delete the default binding by clicking on the arrow to expand it then right-click delete and then i'll add a new 2d vector composite i'll call this wasd now i can set that up to w down to s left to a and right to d all of that tells unity continuously listen for any of the keys w a s or d being pressed and if they are update the horizontal movement action if w is pressed we will have a vector 2 of 0 on the x and 1 on the y if a is pressed we will have a vector 2 of negative 1 on the x and 0 on the y and so on now let's create another action which i'll call jump we'll set its binding to space save the asset and close it you will see that it automatically generated a new c-sharp class for us right click in our player folder and create two new c-sharp scripts the first one will be movement and the second one will be mouse look these are the scripts that we will use to actually move the player and its components we will also need one more script so right click and create csharp script and this will be the input manager now i can shift click to select them all and open it up in visual studios in the input manager we will start off by setting up the basics of the new input system we need a reference to the input controls that we just made to create a new variable which will be type of player controls and i'll call this controls underneath that create another variable type of player controls dot ground movement actions and i'll call this ground movement this will just save us from typing playercontrols.grand movement actions every time we want to access an action now in the awake function we can set controls equal to new player controls and ground movement equal to controls dot grand movement when using the new input system we also have to remember to enable it or it won't work so in on enable we'll say controls dot enable and then the same on disable so on disable controls dot disable great everything is now set up for us to start using the new input system to get input we use the syntax grand movement dot action dot performed plus equals context and then an arrow and then we say what we want it to do context is a variable which contains information about the press and in the do something part we can call a function or set a variable to get input from our wasd keys i will first create a new variable which will be vector2 horizontal input and then in the awake function i can say ground movement dot horizontal movement dot performed plus equals ctx short for context and then i want to set horizontal input equal to context dot read value vector 2. this looks quite complicated but you will understand what it does quite soon to move the player we will use the movement script so go into it and then create a new variable which will be vector2 horizontal input again we'll need a function to receive input so this will be public void receive input this will take input type of vector2 and i'll call this horizontal input with an underscore to differentiate it inside here all we have to say is horizontal input is equal to the horizontal input now in the input manager i can get a reference to our movement script using serialize field movement and i'll call this movement with a lowercase m now in the update function which is called every frame i will say movement dot receive input and i'll pass in the horizontal input to make sure that it's working i'll quickly go back into our movement script and then underneath here i'll print horizontal input now let's return back to the editor we can ignore these warnings for now then select our player and drag on all of the scripts that we just made make sure to assign the movement script to the input manager and then hit play you'll see that nothing much is happening in this game view but in the console you can see 0 0 being printed if i hold down the w key you can see that 0 1 is now being printed if i hold down the a key you can see that negative 1 0 is being printed and same for the s and d keys great now let's make the player actually move back in the movement script we're going to create two new variables these will be serialized field character controller and i'll call this controller as well as serialize field float speed and by default i'll set that to 11. now in the update function we can say vector3 horizontal velocity is equal to transform dot right multiplied by horizontal input dot x plus transform dot forward multiplied by horizontal input dot y we also want to multiply this whole thing by speed so add parentheses around it and then multiply by speed then we can say controller dot move horizontal velocity multiplied by time dot delta time to give us constant movement speed regardless of the frame rate we can now return back to the editor then drag and drop our character controller into its slot i'll zoom out in the scene view so you can see what's happening then hit play great the player seems to be able to move with 8d movement however if i drag the player into the air you'll see that there is no physics acting upon it so it just floats there and we can actually move around in the air to solve this exit play mode and let's return back to the script i'll create a new variable which will be serialized field float and i'll call this gravity and for now i'll set this equal to negative 30. i know that it should usually be negative 9.81 but i've tested it out and negative 30 has a much snappier feel to it you can of course use any value that you want to under this i'll say vector 3 vertical velocity is equal to vector three dot zero now in the update function at the bottom i will say vertical velocity dot y plus equals gravity times time dot delta time and then i can say controller dot move vertical velocity multiplied by time dot delta time you might be wondering why i multiplied by time dot delta time twice but that's simply the physics equation of a free fall now if i return back to the editor and hit play if i drag the player up you'll see that it falls to the ground however if i keep dragging it up repeatedly you'll see that it falls faster and faster until it eventually seems to almost teleport to the ground this is because in our script we keep on increasing our vertical velocity but we never reset it when the player is on the ground to do this let's create a new variable this will be serialized field layer mask and i'll call this ground mask we will also need one more variable which will be bull is grinded and now in the update function we can set is grounded equal to physics dot check sphere for the center will be our transform dot position the radius will just be an arbitrary small number so 0.1 f and the layer mask will be the ground mask physics.hexpear casts an invisible sphere at the location of our player with a radius of 0.1 returning true if it intersects an object with the ground layer and false if it doesn't now i can say underneath here if is grounded is true then we want to set vertical velocity dot y equal to zero now i can return back to the editor assign the ground mask the ground layer and then try testing it out if i drag the player up into the air you will see that it falls down slowly and there's no sign of it speeding up over time great now let's add a jump to the player to jump to a specific height we can use the equation v is equal to the square root of negative 2 times the jump height times gravity to implement this i'll create a new variable this will be serialized field float jump height and i'll set that equal to 3.5 by default i'll also create a new ball which i'll call jump now we need to create a new function so i'll do this at the bottom and this will be public void on jump press it won't take any input and inside it all we have to do is set jump equals true now in the update function before we update our gravity i can say if jump if we are also grounded then vertical velocity dot y is equal to math f dot s k r t for square root negative two multiplied by a drum pipe multiplied by gravity as per the physics equation and after this we have to remember to set jump equal to false in the input manager we have to include our jump since we haven't done that yet so underneath the horizontal movement i'll add grand movement dot jump dot performed plus equals underscore since we don't need any of the context information underscore is just a discard variable and then we want to call movement dot on jump rest we can now return back to the editor and this should be working i'll hit play we can move around and if i hit space we jump great you can also see that gravity is a variable here so i can set it to anything such as negative 30 which i believe feels much snappier or even go so far as to say negative 60 which is a bit too fast for me you can set this to anything that you would like to i'm going to leave at negative 30 for now now let's use input from the mouse to look around when we move the mouse on the x-axis we want to rotate the player on the y-axis since that is what will make it rotate horizontally when we move the mouse on the y-axis we don't want to rotate the player but instead only rotate the camera on the x-axis to do this let's go back into our player controls edit the asset and create a new action i'll call this one mice x set its action type to pass through and control type to axis i'll set its binding equal to delta x on the mouse delta just means how much has it moved i'll right click and duplicate this action and rename this to mouse y and change its binding from delta x to delta y remember to save the asset and then close out now let's go into our mice look script and inside here we can create two variables these will be serialized field float sensitivity x and i'll set that equal to eight and i'll create a new one serialize field float sensitivity y is equal to 0.5 f for now i'll also create a new variable which will be float mass x and also another one for minus y now we need to do the same thing as in the movement script so public void receive input and this will take in a vector2 for the mouse input i'll set minus x equal to mass input dot x and minus y equal to mouse input dot y we'll also have to remember to multiply both of these by the corresponding sensitivity now above here i'll create an update function and i'll say transform dot rotate rotate around vector3 dot up which is the y axis and i want to rotate by minus x multiplied by time dot delta time now in the input manager i'll create a new variable for the script serialized field mouse look and i'll call this mouse look i'll also create a new vector 2 which will be mouse input now in the awake function i can say ground movement dot mouse x dot performed plus equals ctx and then i want to set mouse input dot x equal to the context reading the value of a float i'll do the same for my sy just copying and pasting that line and now in the update function i'll also say mouse look dot receive input and i'll pass in the mouse input now we should be able to go back to the editor and this will only work for the horizontal movement for now select our player and make sure to assign the matched look to its corresponding slot then hit play if i move my mouse around you can see that we can look around on the x-axis but moving my mouse up and down doesn't do anything of course we can still jump and move around great let's exit play mode and return back to our mouse look script in here i'll create a new variable which will be serialized field this will be transform and it will be the player camera i'll also create a new variable which will be type of float and this will be the x clam i'll set this equal to 85 by default we use a clamp to ensure that the rotation never goes too high or too low so that the player can look directly behind them since that isn't how most fps games work i'll also create a float for the current x rotation and set that equal to zero by default now in the update function at the bottom i can say x rotation minus equals mouse y you might be wondering why we're using minus equals and not plus equals but you can try them out and you will find that if you use plus equals the controls are reversed as to what is normal next i'll say x rotation is equal to math f dot clamp i'll clamp x rotation between negative x clamp and positive x clamp finally i can say vector3 target rotation is equal to transform dot euler angles to get the current rotation of the player and then target rotation dot x can be set equal to x rotation now i can set the player camera dot all the angles equal to the target rotation great description now be done let's return back to the editor make sure to assign the player camera into the mice look script and hit play as you can see i am now able to look around freely move and also jump just to quickly fix up some things in the script i'll return back into the movement script and remove the print statement since we don't need that anymore and at the top i'll also include hashtag prima warning disable and i'll say disable the 649 warning what this means is that if we return back to the editor these errors that tell us that a variable will never be assigned will go away this is because when we use a serialized field we are expected to assign the variable a value immediately as unity doesn't realize that we can assign the variable in the inspector we will do the same thing with the mouse look script and now if we return back to the editor those warnings should be gone you can see that we have two more and these are from the input manager script which i forgot to do so now if we return back to the editor everything should be fixed and all working i'll clear the console maximize the game view and now we can play great there's one more cool thing that you can do with the character controller which is if you go into the inspector you will see all of these values that you can play with for example step offset defines how big a step the player can move up so if you have stairs in your scene the player should already be able to move up them without any further scripting the slope limit is the same but for slopes apart from that just mess around with it have some fun and learn cool new things that's it for this tutorial thanks for watching and i'll see you next week
Info
Channel: Practical Programming
Views: 27,775
Rating: undefined out of 5
Keywords: unity, tutorial, unity tutorial, fps, fps controller, new input system, unitys new input system, input system, unity input system, fps controller unity new input system, intermediate, beginner, new input system tutorial
Id: tXDgSGOEatk
Channel Id: undefined
Length: 27min 10sec (1630 seconds)
Published: Tue Feb 02 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.