How to Rebind Your Controls in Unity (With Icons!) | Input System

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys today I want to show you how we can use unity's input system to rebind controls for our game this is pretty robust and it has a lot of functionality and I will walk you through every step so that we're all on the same page including how to remap controls for multiple control schemes in my case I'm doing keyboard and Gamepad and I will show you how we can display text for the rebindings as well as icons ready let's go so here's my scene and I really have nothing going on except for a simple menu with some settings that I can go into which are completely blank when I go into them so we'll build the rebinding UI together but if you want to know how to build a menu like this one especially if you want to be able to scroll through the buttons with your keyboard or Gamepad and not just click with your mouse then I have a tutorial right here that will show you how to do that I've separated the keyboard and Gamepad controls because I checked out a few other games and that's how most of them handle it so we'll build this like a commercial game does so to start we obviously want to make sure we've installed the input system from the package manager but just as importantly we want to open up the samples drop down here and import the rebound finding UI sample Unity has already put together a set of scripts and prefabs to make this really easy for us their script is hundreds of lines long and does the job really well so to save time we'll use theirs and add functionality on top of it to make it as awesome as possible so first let me show you how we set up our controls so we would right click and create a new input action I already have one called controls now normally I like to generate a c-sharp class for my controls but in order to rebind controls we're going to have to do this a little bit differently so leave that unchecked and instead let's click edit asset and dock it over here so first you create your action map you might use this to separate things like gameplay controls versus UI controls or mini game controls stuff like that for this I've just got an in-game action map next you want to set up your control schemes I already have my two here Gamepad and keyboard but when you create one you just want to make sure you type in the name click the plus button here and then select whether you want it to be optional or required when we're done let's just make sure that we set this back to all control schemes so that we can set up both sets of controls at the same time so now in our actions section I've created all the actions I needed for this little demo scene so for this I have four button actions Dash attack jump and menu open close within each each of them I've assigned both a keyboard and a Gamepad binding you can just press the listen button to find them easily and be sure to assign them their proper control scheme over here and finally I have a pass through with a vector 2 control type a vector 2 control type will allow you to make up down left right Composites I've made four of those one for wasd one for the arrow keys one for the analog on my Gamepad and one for the d-pad on my Gamepad depending on what you want you might want to change the mode here especially for things like analog sticks that aren't just zero or one they have in between states with digital normalized I'm using my analog stick right now and you can see that he snaps to full movement or no movement at all and digital works the same they both behave the same it's just that the returned result of digital normalized will be normalized and digital won't be analog on the other hand you can see I can control his speed depending on how much I'm moving the analog stick so for mine I'm going to switch this back to digital normalized now let me show you my preferred method of actually detecting these inputs with code I've created a user input script and attached it to my input manager object here and before we open it notice that I've added a player input script here as well this comes with the input system and essentially if you want to do key rebinding or make use of Gamepad rumble or any kind of advanced stuff with your input you're going to want to use this it just makes it all so much easier to do so you can plug in your controls here we can leave our default control scheme to any and our default map to in-game now for the user input first off I made it a Singleton this makes it easier to reference and will only ever have one of those so it's a perfect use case for a Singleton now what you want is going to depend on your controls obviously but for me these are the inputs I want to detect based on the mechanics my player has I have a reference to the player input that I just showed you and I've set up input actions for each of the actions in our controls to set those up we grab them from the actions within the player input script and it utilizes strings so make sure you get your spellings and capitals correct here then in our update we can actually update all these public variables from up here the move input we can just read value and return a vector 2. and the rest we can use either the dot was pressed this Frame dot is pressed or dot was released this Frame function depending on what you want to return now this is a nice solid script to grab your input from to call these for example I'll just show you my movement I'm referencing user input.instance dot move input you don't need to do get component or anything like that because this is a Singleton and this value will get read with either your wasd keys your error keys or your analog stick or your d-pad on your Gamepad which is awesome okay so we're on the same page now we have our controls set up let's set up the key rebinding system now so in samples input system 1.5 or whatever version you're using rebinding UI take this prefab and I'll drag it into my keyboard canvas first and before we change anything I want six of these lined up nicely two for movement wasd and arrow keys one for dash attack jump and menu open and close [Music] let's make these child objects of a rebindings object and we'll use the grid layout group with a cell size of 100 on the X and 50 on the Y and let's scale these up to 1.75 that's looking pretty good I also want a reset all button above my back button here so I'll add a text message Pro button and we'll leave that as is for now how many rebindings you want is up to you if you go to the rebind action UI script here and assign your input action and click binding you can see all your options we can do wasd all at once or we could separate them individually whatever you want I will keep mine together here and right off the bat there's already so many things I want to change about this the first of which is to upgrade this to text mesh Pro I don't like the Legacy text and I have no idea why they built this using that now you won't be able to just reference text mesh Pro in here you're gonna have to go to this assembly definition asset and add unity.textmesh Pro over here now we want to replace these three text fields in the code with text mesh Pro instead if you highlight this and click F12 it'll take you down to our serialized fields and let's replace these text Fields with text mesh Pro as well so here here and here we'll replace text with TM Pro dot text meshpro U GUI now that the code is done let's actually change this prefab and update the components so the action name text should be text mesh Pro in the trigger rebind button the text should be updated to text much Pro as well and in the reset to default button this never changes but let's update it to textmas Pro as well to keep things consistent okay awesome so we're done with this prefab so for our first button here let's make sure we've assigned everything we've got our action plugged in I'm changing the wasd binding and for the action label plug in our action name text for The Binding text the action binding text now these last two we need to create so let's create a new panel and we'll call it wait for input panel throw it at the bottom so it's drawn over top of everything else [Music] and inside of it create a text mesh Pro called wait for input text and make sure the panel is inactive because it'll be activated with code when it's needed and so finally let's plug in the wait for input panel here and the wait for input text here so let's go ahead and test this and we're going to get an error here that's because it won't let you rebind keys that are currently enabled so let's go back to our rebind action UI script and let's find the perform interactive rebind function and after the cleanup at the beginning let's disable our action and then we'll enable them again in the on cancel operation as well as the on complete operation so no matter what our controls get re-enabled as soon as we're done with this function let's go ahead and test this again and now it should actually be working I can remap this to these keys and now I'm moving with those new keys so real quick let's plug in everything for all the rest of the keyboard keys and you can see that we've got a few different display options here I'll include the documentation in the description for anyone who's interested now there are a lot of potential issues here first of all once I click this to remap it there's no way to cancel out of this let's fix that first back in our script within the perform interactive rebind function we can add a DOT with canceling through and you can actually see there's all kinds of options that you can make use of here but we want a way to call this dot on cancel function and we can do that by adding dot with canceling through and for me I'm going to do that with the Escape key on the keyboard and actually while we're here you can exclude certain types of controls in the same spot the way I set up my controls this isn't really necessary for me but if you set it up differently without assigning control schemes you might for example accidentally click your mouse button and then that will be your new key rebinding which you don't want so if that's the case for you you can use dot with controls excluding and you can do mouse or just specific clicks on the mouse whatever you need but again if you set Yours up like mine this shouldn't be necessary for you at least not for different devices okay our next problem you can see if I go to rebind my wasd I can just press up up up and it accepts all of them we obviously don't want that so let's add the option to ignore duplicates so down here let's create a function called check for duplicate bindings and we'll add an input action binding index and Bool argument and let's default that to false so first we'll get the new binding to check for the duplicate we'll iterate over all the bindings in the action map and if the current binding is the same as the new binding we'll skip it and if the effective path of the current binding matches the effective path of the new binding then a duplicate binding has been found and will log a message and return true next if all composite Parts is marked as true then we'll iterate over all the bindings before the current binding to check for duplicate composite bindings and if the effective path of the current matches the effective path of the new binding then again we have found a duplicate and will log a message and return true and if no duplicates were found simply return false now up here let's check for duplicates before updating our binding display so if we have a duplicate binding we'll remove that binding override we'll call the cleanup function and call this function again before returning so we can try a different key and then return so let's test this now if I press W more than once we get that message and I'm forced to pick another key and if I try to use W down here it won't let you do that either now we aren't out of the woods yet but before we continue let's make sure we have all these reset buttons hooked up correctly they should all be calling the reset to default function from the parent object's rebind action UI script as well now let's say I change my Dash to a 1 and my attack to a z which is what my Dash was before and now if I reset my Dash you can see that we did manage to get a duplicate in there which is no good so let's fix that so in the reset to default function we're going to comment all of this out and you can do control K and then Ctrl C to comment it all out at once instead we're going to create a reset binding function we'll cache a reference to the current binding remove the current binding and then create a for each Loop to check all the actions in the map so if the other action is equal to the action meaning if this is the original action then we'll just skip it and continue otherwise we'll check all bindings for duplicates within the action so if the override path is equal to the new bindings path then what we'll do is swap the bindings so let's call this here and I'll show you what I mean so if I do the same thing as before I'll change my Dash to a 1 and my attack to a z now let's reset the dash you'll see that the two have simply swapped places instead of allowing the duplication to happen alright next maybe you don't want this name to derive directly from your action but you'd like to give it a name yourself so let's add in the option for that so the appearance of this script in the inspector is controlled by this editor script here that's how they get it to look nice with all these little headings here and stuff so let's expand what they already gave us so before we go into the editor script let's go into the rebind action UI script one more time and add two fields we want a public pool called override action label and a private serialized field of type string called action label string so you'll notice right away that even though we made those public and serialized they aren't showing up in our inspector here that's because we now need to change the editor script so first down at the bottom let's add a serialized property called action override property and action override string property and these here are how they divide the script into sections like they did so let's add a new one called customize UI now back at the top in the on enable method let's assign the properties we just created by finding those properties what goes into the strings here are the variable names from our rebind action UI script that we just set up okay now go into our on inspector GUI function and let's add a customized UI section and we can basically just copy the one from the UI section above except let's replace this label here with our customize UI label and obviously swap our properties for the two that we created below okay so now you can see they've been added but honestly I'd really only like this string field to show up if we've selected this pool here so back in our editor script let's get a reference to our rebind action UI script and assign it as the Target in on enable now we can add an if statement in here if our override action label is true then we'll display the string field now you can see that's working in the inspector very cool but this doesn't actually do anything yet so in our rebind action UI script we need to make a tiny change to the update action label function let's make it so that if our override action label is true then we'll make the action label text to be equal to our string and if not then we'll throw in the action name if it's not null and finally let's delete our string whenever we make it false as well so that it doesn't actually remember what we had written there before now if we set this to true we can call it whatever we like and if not it'll grab the name from the action map instead awesome next I'm going to set up the GamePad canvas the same way we did with the keyboard [Music] I'm not going to rebind the movement here because the analog and the d-pad are fine and I'm not sure why you'd want to rebind those but you can if you want but for this we're going to do icons instead of this ugly text so Unity has actually already provided us with a handy little script for this as well what you want to do is put it on the parent object of whatever is holding all your rebindings so for me I'm going to put this Gamepad icons example script on my Gamepad canvas here so basically this is going to check to see if you have icons assigned based on the control path and if there are it'll automatically turn off your text and turn on the icon you could set this up for the keyboard as well if you want nice little icons instead of the text you would just need to get your own icons and expand this functionality for all the keys on your keyboard and if you don't know what the path names are called you can click this little T here in The Binding path and it'll show you the proper path but now we just need to assign all the icons I don't have a PS4 controller so I'm just going to plug in the Xbox icons they give you icons for both which apparently are from opengameart.org but they're all in this folder here so let's assign them you don't need to lock your inspector over here you can just right click and hit properties and drag this over here and assign them that way it's much easier okay let's do this really fast [Music] so if you try this now it's going to give you an error and that's because we need to add an image to our prefab and it needs to be called this exactly so let's add that in and disable it let's give it a width and a height of 24. now it should be picking all those up automatically based on your control scheme awesome next let's get that reset all button working create a script called reset device bindings and I'm going to attach one to my Gamepad canvas and one to my keyboard canvas now if you have all your bindings on just one canvas meaning you actually want one button to reset all of your binding overrides then you could simply just create a function to remove all binding overrides however if you have yours separated like mine we don't want the reset all button in the GamePad to reset the GamePad and the keyboard bindings just the GamePad bindings and vice versa so let's create a string to hold the name of our device and create a function called reset control scheme binding so first we'll Loop through each of our action Maps then we'll Loop through each of the actions within that action map and we'll remove the binding override if the name of the binding group is equal to the string we set up here now it's important to distinguish the fact that we are not talking about the device within the binding path we are talking about the control scheme group we manually set up in here so the spellings from there need to match now let's fill in the controls here and type in our string for each binding group and let's not forget to assign that method to our buttons on click event for both canvases and now you can see I'll mess up the keyboard controls and I'll mess up the GamePad controls and now we'll hit reset all and all the GamePad controls have been reset but if we go back to the keyboard you can see that it's still kept the ones that we changed perfect so this is all working except for the fact that we lose our rebindings as soon as we exit play mode and that's no good and again Unity has actually already given us a good solution for this as well they created this little script called rebind save and load let's attach one to our Gamepad canvas and one to our keyboard canvas let's go ahead and assign the input action asset on both you can see if we look inside it's saving our data within a Json file called in a string called bindings when we disable this script it saves and when we enable the script it loads so you can see I'll mess up my keyboard and my gamepad and we'll exit play mode but if we go back in it loads up all the stuff that we just set well this one was a lot of work to put together guys so if you enjoyed or you got anything out of it please hit the like button share comment all that good stuff to help get this video shared with more people let me know if you have any ideas for improvements or anything like that so that we can all benefit from this tutorial as well see you in the next one guys I want to give a very special thank you to our Hall of Fame patrons Jacob yondak Xander Kessler Darren Perrine throbbing wind Fontaine weight and couch as well as our Early Access patrons Ziona and Ken Wade if you choose to support us on patreon you can get early access to all our videos monthly Alpha builds and more
Info
Channel: Sasquatch B Studios
Views: 15,996
Rating: undefined out of 5
Keywords: unity, unity2d, tutorial, unity tutorial, sasquatch b, sasquatch b studios, unity beginner tutorial, unity input system, unity UI, unity how to rebind keys, unity how to rebind controls, unity rebind controls, unity rebind composite, unity rebind keys input system, unity rebind controls input system, unity rebind keys with icons, unity rebind controls with icons, new input system key rebinding, custom key bindings in unity, unity persistent rebinds, persistent key rebinds
Id: qXbjyzBlduY
Channel Id: undefined
Length: 20min 29sec (1229 seconds)
Published: Thu Apr 20 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.