Unity's New Input System: The Definitive Guide

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
the new input system is a much cleaner and flexible way of gathering the player's input but this flexibility comes at the cost of more complexity the old input system worked like this if I right click create c-sharp script just call this player control double click to open it up I'll just clear up the start and the update method we would have to say if input Dot getkey and we could do key code dot d and then we can say something we would call a method like fire the gun or something so I'll just put in quotes here fire the gun and let's say we also wanted to interact with an NPC we could say if input dot get key and key code let's say it was keycode.a and then we would say interact with an N PC okay now what if we wanted to do you know jump we would say if input dot get and so on and so on and so on so you get the point here right all of this repeatable code makes things quick to implement but also not flexible at all the problem arises when you want to change the buttons change the behavior of the buttons or most importantly you run into a huge problem which essentially breaks the game when the gameplay switches for example say you are building an FPS and have multiple gameplay situations like driving a car swimming underwater and moving on land the arrow keys or if you are on a controller the GamePad will be your primary way of moving around but how can you tell which state you are in how can you tell if the player is using a keyboard or a controller after all the player cannot alter any of these controls in the old input system the most clear solution would be to check different Bulls every frame for every single different situation but this would mean you would have a pile of code a long list of nested if else statements all hard-coded all dependent on the keys that are unchangeable and not to mention the performance would take a massive hit having all this checked during the single update method and this is not even accounting for all the other game objects you will have been constantly updated during each frame by now you should be convinced that the old input system has these detrimental flaws so the next question is how do we use the new input system to fix these problems and how are we supposed to implement it properly the new input system fixes these game breaking issues using input action assets what is an input action asset simply put an input action asset stores all of the action maps and therefore all of the possible player controls so to create an input action asset we will click on window go to package manager click on it and instead of packages that has in Project we will go to Unity registry and we will search for input system as you can see I have it downloaded here and if yours says update make sure you update it but if it says install then just click the install button already have it though so I will continue now right click on the project tab hover over create and at the bottom of the drop down menu we will select input actions I'm going to rename this to player controls because it will handle the controls from the player now double click to open the input action asset and we are greeted with this new window which at first can seem intimidating if you have never seen this before but I'm going to walk you through every feature and show you how to use it properly in the top left corner you can see the control schemes drop down this is for separating different devices so the input does not get mixed but this is not necessary to create as we can just set up each input for each device wherever we want so this is not needed I'm not going to do this to begin we need an action map so let's click on the plus button on the action map column an action map is a container for the current state of the gameplay and will affect how the input from the player is interpreted for example if you wanted a basic container that held all the controls for when your player moved around and interacted with the world you can create an input action asset named basic gameplay but if you wanted an underwater section you can create another input action map called underwater section one for driving one for flying Etc the main thing I want you to remember is why we separate these different and put action Maps let's say we're on a computer the arrow keys will move the player but now the player is underwater we now have the ability to switch the action maps and the controls will now register differently because of the current enabled action map so our up key will now be to swim to the top instead of jump but then our controls for flying are different no problem we just switched the action map and then we can go back to the basic gameplay when we switch back to it the input action map tells your game what state the player is in and how it should treat the input it is receiving so let's create a basic input action map we'll call it base combat okay I created an input action map now what now we can look over to the column on the right and see that it says actions this column is just what it says it is it is the specific actions for what the player does for example moving jumping shooting Etc so this column is the bridge that connects the physical input from the player and the actual data given to your game for example say the player moves using the arrow keys we can create an action named move which takes a different pressed arrow keys as input and gives our game the data where we can later code with this data to make the player move remember the action is a bridge that connects the physical input the player puts in and spits out data based on that input the next question how do we set up certain inputs and how do we determine what kind of data we receive to create an action we will click on the plus icon on the top right corner of the action column by default it has already created one for us I'm just going to go ahead and delete this cut and to create a new one we could just click on this plus icon for this first action let's name it jump because this action will handle the player's jump as you can see multiple things have occurred after creating just one action for starters underneath our created action we have what is called a binding the column to the far right now contains a new list of options and we also have a plus icon for our newly created action let's break down what each one is and find out how each one works let's start with the binding what is it remember when I said an action is the bridge from the physical input from the player to the data in the game The Binding is the start of that bridge bindings are the physical controls on a device that the player can use okay but how do we set a specific input to The Binding if we look in the right column we can see this path option Under The Binding drop down we can click on it and find whatever physical input we are looking for and unity makes this extremely easy by simply clicking the listen button and touching whatever key we wish to activate this action this is where the new input system really begins to shine as we can not only hook up keyboard controls but we can also hook up mobile device controls and console control controls for PlayStation and Xbox ssy control schemes aren't really necessary as we can manually hook up all the controls ourselves because we are in a jump action I'm going to make this action trigger by the space bar now Under The Binding drop down we have two more subsections interactions and processors interactions change how the physical input can be activated for example what if we wanted the jump to occur by double tapping the space bar or holding it down the new input system offers this variety to customize the gain to your needs for me simply pressing the spacebar works so I will leave it blank so what is the processors tab the processors tab can modify the value received for example say you wanted a control to be inverted or clamped to a certain range then you could come in here and add a processor I haven't used this yet so I can't offer an in-depth analysis on everyone but I would recommend you check this out if you are interested in either inverting your controller values having dead zones which are primarily for controllers when you slightly push down on buttons or slightly move the joysticks The Dead Zone means it will not activate until it is beyond the set value of pressure if you're interested in tweaking your received physical input you might want to experiment with this so we have built the first part of our Bridge with the physical input we need to build the other side of the bridge which requires data we received from the physical input if we select our action which is tabbed in green we can see that the Action Properties panel is slightly changed it will now have an option marked action type this is where we decide what data we would like to gather from our physical input in this case the input comes from us when we hit the space bar so if we click on the action type a drop down menu appears with three different options value button and pass through let's start with button this is a one-time action which sends data of the key on a keyboard or a button on a controller in this case the space bar is being pressed but if you alter the interactions as I showed you earlier then the data will be received based on how you alter the interaction more uses of button can be seen with firing a gun whether you press or hold down the trigger button or perhaps a melee where you press another button and so on since button handles all of the singular action controls such as jumping or shooting we need controls that can handle and update the movement of the character after all the analog sticks on controllers are not buttons and even if they were like a computer keyboard with the arrow keys we would still need different data gathered because we need more information to move and rotate the player than just knowing that a button was pressed this leads us into the next action types value and pass-through these both update continuously as the control changes which is why these are both great for player movement the only difference between these two options is that passthrough ignores the disambiguation process this just means that when multiple devices are hooked up in the game you can affect the player using a controller a keyboard or whatever other devices or controllers you have hooked up but value only listens and follows one device's input per player which is why I only use button and value passthrough requires a specific type of gameplay to be applicable and when I play a game I'm just sticking to One controller or One keyboard so I haven't found a use case for passthrough yet you can see that if we have value or pass through selected a new Option appears named control type this is where we decide what information we want to gather from our value action type for movement we want Vector coordinates to move our player which can be found at the bottom some of these other options can be useful but during my time using unity's new input system I have only used Vector 2 Vector 3 quaternions and touch for mobile games you can look into the other options if you want but you can make almost any input mechanic with the main control types listed above since I'm a since uh since I'm making a jump mechanic first I'll leave it as a button you can see the initial State checkbox under the drop down menu as well this simply checks whether your player is holding down a key or button before the game starts I'm going to leave this unchecked and finally we have the plus icon on the action itself if we click it we are presented with a drop down menu with the first option rating add binding when clicked this will add another way of executing the action for example under jump we have the space bar as the physical input to trigger this action what if we made a cross-platform game and one of the Xbox controllers a button or the PlayStation's x button to make the player jump or even if we wanted to have multiple ways to jump in the game on keyboard let's say w we can do that as well so let's add these new bindings for controllers Unity makes it very easy to add the lowest button on the controller out of the four main controls is called the button South which works for PlayStation's X and Xbox's a button the rest of the controls follow this pattern with button East button West and button North let's take a look at more of the drop down options if we click on it again the next option is for positive and negative bindings this is made for two buttons for seeing which direction the control is moving in it will be negative moving in the minimum value Direction and positive moving in the maximum value direction if it is in the middle you can decide which side wins I haven't used this binding yet as it is very specific to the type of gameplay you want if you're going for a mechanic that has a two button pressing feature maybe like balancing on a rope or a tall building I can see this as being used but for my game it is not needed the next options are to add bindings with one or two modifiers if we select this we can see a new binding has been created along with a modifier this feature is used for button combinations say you want it to have a super punch that is activated when the user presses two buttons at the same time or maybe you have a Sprint mechanic that shares a key with a walking mechanic but this is where modifiers come into play this feature is used when you want button combinations then this is a great feature to have one more thing I forgot to add if you change your control type to a vector then select the plus icon on the action you can see an upright left down composite is created you can do this manually but this is a nice shortcut for making the player movement action bindings a composite is just a group of keys referencing the same action if we select the composite holder we can see a composite type and a mode the composite type just holds the specific types of bindings like modifiers as shown earlier or vectors for movement the mode defines what we should treat the input as either as analog digital normalized or normalized digital normalize treats the input as buttons so each direction is marked as zero or one one for pressed and 0 for not pressed digital means the same thing X except the values are not normalized for example if you hold down the left and up key the player will appear to be going faster because the inputted Vector has a length greater than one it can be best represented as a box shape while digital normalized can be represented as a circle shape digital normalization makes sure that your player moves at the same speed in all directions the last option is analog which marks your inputs as floats rather than ones and zeros this is for controllers as you can slightly move the analog stick without moving it fully to the maximum edge of the analog stick radius so you can have a value of 0.5 on the right which means you have moved it halfway to the right side of the maximum value which is one with all that out of the way let's set up our jump action back to a button type save our input action asset and start looking at how we can actually use this to affect our player in our game so before we close this input action asset another good way to do this is to just check on the autosave box so you don't have to save it every time and now with the input action asset selected in the project tab we can see another empty checkbox to generate a c-sharp class for the player input let's go ahead and check that to make sure that all of our gameplay mechanics are created if you have made it this far congrats all that is left is to show you how to actually implement it into your game to start let's find our player and add the component player input on him once added this component has some available fields which are actions UI input module camera and behavior let's drag our input action asset we just created onto the action slot let's set our default map to the action map we just created and and the UI input module on camera we can leave blank as the UI input module is for interacting with UI elements like menus and pause streams and the camera is only required for split screen setups when you need to determine which camera is attached to which player but for this case we'll be simply moving the player which does not involve interacting with UI or split screen multiplayer the last option we can change is the behavior this will determine how you choose to receive the actions the player inputs we have four ways of getting notified that the player has inputted something if we click on the behavior button a drop down menu appears and we have the option to send messages broadcast messages invoke Unity events or invoke c-sharp Events first of all none of these are wrong they all have their own ways of implementation I will go over all of them show you the process of each implementation and give you my opinion on them as well to show you how it'll work let's take the one control we have a spacebar when we hit the space bar we need a method to be called that takes the player and forces him into the air the therefore making him jump hopefully that's straightforward enough so where do we put the method and how do we call it to solve this let's create a new c-sharp script called player controller and drag it onto the player object this is the script where we will call our action methods let's also add a rigid body 2D component to the player in order to have the player move in game using physics to demonstrate how our first Behavior Works which is send messages let's take a look underneath the behavior option and we can see a list of actions on device lost on device regained on controls changed and our action right after except it is not named jump but on jump this is because send messages calls your jump method with the on word before your actual action name for example if our specific action action if our specific action was called jumping it would be called on jumping if the action was called go higher it would need to be named on go higher the only other requirement for making this work is to make sure the script for calling the method which we will create in the new script we just added is attached to the game object we already added the script component to this game object so now we just need to call it let's double click to open up our new player controller script to start let's get a reference to our player controllers and our rigid body 2D in order to use the new input system let's also get access to its namespace so to get actions to our player controllers we can just say private player controls which is our input action asset and we can just call this player controls we also need to get access to our rigid body 2D so let's create a private rigid body 2D called RB and then we can just assign this in the start method player controls is a new player controls RB we are going to get the component of the 2D rigid body now let's create our jump method remember we need to add the word on before we call our jump and that gets called when our action is performed so I will write private void on jump with curly braces and in this method we can write the logic to see if our method is being called let's first just write debug.log jump let's go back into unity and play the game to see if our method gets called and as you can see every time I press the space bar our method gets called now let's actually make him jump we will go back into our player controller script and add a force in the upward Direction so I will write RB dot addforce vector2.up times whatever our gem force is going to be I'll just say five for now then comma Force Mode 2D dot impulse just to make it happen immediately now if we go back into our game and press play every time we press the space bar our player will jump into the air let's test it okay now what does broadcast messages do as you can tell if we switch the option from send messages to broadcast messages the on jump syntax and the rest of the on-device regained lost Etc that all stays the same and let's press play and see what happens let's press play now when I hit space the same thing happens so what's the difference send messages and broadcast messages has the same syntax and it appears to work exactly the same well that's because broadcast messages and send messages are exactly the same the only difference between these two are that with broadcast messages you can have this on jump method Beyond any child game object of the player so send messages looks for the method only on that certain game object we put the script on so for the character base here we have the player controller on the same object as the player input or send messages this would work if we have the player controller in one of these child objects it would not work but if we had broadcast messages and we put this player controller on one of the child objects that would work so send messages looks for the method only on the specific game object the player input component is attached to while broadcast messages looks for the method on this object and all of its children usually all of my player input will be in one script so I believe send messages is better but if you have scripts that the player can input methods on and your children objects as well then broadcast messages is for you beside that small detail they function exactly the same let's take a look at our next Behavior invoke Unity events if you have ever used buttons in unity before this will be very familiar for you when we select invoke Unity events the on jump syntax gets dropped along with all the other on blank methods and in replacement of this we have this events drop down and if we click to open it up we can see the device lost event device regained event and controls changed event along with our action map drop down you can start to notice how all these are basically the same but the implementation is starting to get a little different so let's create on the action map we created or base combat and it now opens all of our actions for this specific action map right now we only have jump which is our only action so that's the only one present but if we had multiple they would all be stationed here as well with the invoke Unity events Behavior what we do is create the method in our script the same way as send messages or broadcast messages and note that the method can be named anything you want for this it doesn't have to be on jump or on move you don't have to use the on keyword what we would then do is drag whatever game object our script is on into the correct event slot because our script is attached to our player object we just drag our player object onto the jump event if we click the sidebar drop down menu we now have access to all the game objects components but we are looking for the script component that holds the jump method so we can select the player controller component and click on the method we have created in the player jump but because we are selecting it in the inspector we need to make this method public so let's go back into our code and change the method to public now when we select the player controller class we can choose the jump method let's run our game to see if it works let's go back into our game see if it works that's my dog literally and as you can tell it does work but our player goes higher than before why does he do that when we press the key it triggers three times one for the start of the button being pressed one for the button press and one for the end of the button press so this method is being called three times which explains why our player is going a lot higher but we only want to call it once to solve this we can go back into our code and tell our code and tell our code cold to only register one of the three occurrences of the method so if you don't already at the top have using Unity engine.input system you need to write that in because we need to gather more information about the specific input and in this method we can now pass in the input action.callback context and we'll just call it context and all we need to write is if context.perform then add our jump logic because our jump gets started performed and canceled so we only want to call it once so we only need to call one of these different properties if we go back into Unity we can see under the events the Callback context as a parameter by default this is just to gather more information on the action and can be very useful especially when we Implement movement using Vector twos another drawback I found just now is uh if you change the method then you have to reassign it they just found that out there you go so we can see if we press the space bar there we go he doesn't go as high and he only jumps once okay awesome so for our last Behavior we have invoke c-sharp events which is identical to invoke Unity events except we have to manually set everything up in my opinion this is the worst behavior because who wants to manually have to set the entire event system up and code when Unity offers a more streamlined version themselves but I'll still show you how to do this if you just prefer having everything in code and maybe or more used to writing events in plain c-sharp for this we will need to create an on enable and on disable functions to enable every single action we have and to disable it to start we will enable and disable the action map and also enable and disable the jump method we have and now we just need to call the action to our method and it is now set up now we can call the action and our method is set up see in the enable whenever we're going to jump we subscribe to this method and then we also unsubscribe as well for the disabled and you can imagine this can get very tiresome and long especially when we have a lot of other inputs like movement fire Dash slide driving Etc you're gonna have to do that for every single different action you want you're gonna have to subscribe and unsubscribe and not to mention you're gonna have to do all the logic as well so it would be a lot easier just to do the logic and that's it so that's why I don't like it but let's go into unity and see see how this works again we have invoke c-sharp events if we press play if we hit the space bar null reference exception let's see what it is line 18. it's not set to a reference line 18 player controls dot enabled uh maybe this needs to be in the awake function let's see if that works as this just goes to show you how little I use the uh c-sharp events just because it's not that great and there we go it works so yeah if you're going to use plain C sharp events you could have to put in the awake and not the start method but yeah as you can see it works just the same all of these are exactly the same it's just how you're going to implement them and there are four different ways you could Implement them it's just up to you so those are the four behaviors you could use again all of these accomplish the exact same task but they all have their own unique way of being implemented the send messages behavior is the most straightforward it's also the quickest to set up it's what I'll be using when I show you how to implement the player movement as well you can choose whatever Behavior you would like broadcast messages work the same but it just adds another layer if you're gonna use send messages or broadcast messages I'll just stick with send messages for Simplicity invoke Unity events is a good choice as well just because it is visually friendly and you just have to manually plug in your methods for each of your events but Unity sets this up for you so this isn't a bad choice either and for your last option which is invoke C sharp events this puts all the work on on you you have to manually set up the entire event system yourself so for that reason I find it the least practical and often the most time consuming overall I think it's the worst of the bunch if you're gonna do C sharp events just use Unity events otherwise I would use send messages unless you have children which have input scripts as well then broadcast messages is better I tend to only stick to Unity events and send messages for the player movement example I'll be using send messages for the last example of unity's new input system I'll show you how to move your player in the scene to start let's open up our action asset and in our action map let's hit the plus icon to add a new action we'll call this move we'll assign the action type as a value and then the control type is a vector 2. now when we click the plus icon for this specific action we can select the add up down left right composite so let's click that we will leave the composite type as a 2d vector and the mode as digital normalized in order to avoid any diagonal buggy Movement we can name this wasd for the wasd keys and now we can assign each of the composite type bindings for each keep for up it'll be W down s left a and right d let's hit save asset and now that our action is created if we look at the player input component on our player we can see the on move text which means it's time to create this method let's open up our player controller script and create a new method which we have to name on move we also have to change this jump method to on jump so let's do that so this is going to be a bit different than the button because we need to gather more information on what keys the player is inputting to gather more information we can pass the input value into our own method so we go input value and we'll call this input value now to get the vector 2 out of this we simply say input value dot get and the type is vector2 so we'll say Vector 2 and circle braces to finish now we can set the rigid body 2D velocity equal to this Vector 2 multiplied by a move speed so let's really quickly create a move speed variable and I'll make it serializable so we could assign it in the inspector okay so we're going to go back into the game and try this out let's hit play and all right I can still jump oh our move speed is zero I was like why isn't he moving so let's if we up the move speed I'm just gonna say five right now I hit the right arrow key also it's wasd not the arrow keys if I hit W there we go a moves him left D moves him right you can see he's turning a little bit just to fix this we can just go on a rigid body click on freeze rotation on the z-axis now when we move him there we go he moves a and then D you could jump and yeah if we wanted to add the arrow keys it's very easy that's why that new input system is great all we would need to do is go here to move let's delete this binding move and add another composite and we could just say arrow keys and we could just do the same thing listen for the up Arrow for the down arrow listen for the downed to the left left and the right right okay now watch how easy this is we just saved the asset and I don't have to do anything else after I added the those keys we could add whatever Keys we want to it now if I use the arrow keys it doesn't work because the move speed's set to zero I'm gonna go out of play mode and set this to five here now if we try it if I have the arrow keys we can move it either way and I freeze here's a little note whenever you change something while you're in play mode it's not going to save so there you go but if we move left to right using arrow keys it works we could jump still and if we use wasd we can move as well so that's flexibility you have with this new input system you could add multiple bindings to one action and that's gonna do it for me I hope you all enjoyed the tutorial leave a like if you did and let me know what you guys want me to cover next
Info
Channel: DmanGames
Views: 16,077
Rating: undefined out of 5
Keywords:
Id: ZSP3bFaZm-o
Channel Id: undefined
Length: 32min 6sec (1926 seconds)
Published: Mon Jun 26 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.