OMG, LOVE YOU!
Tutorial - Ingame keybinding
Sometimes you just want to let your players set their own keys to interact with your game, right? Be it through an Options Menu, or as I did in the last update, within a tutorial. It's very important that your player can configure his/her own way to interact with the universe of your game. So let's talk about how we can do it in Godot Engine.
What we will need?
In Godot Engine there is a class that is responsible to handle how the Inputs of your game are mapped to the available actions, the InputMap class. Actions are, basically, arrays of inputs that communicate InputEvents to your game system. You can add keyboard, mouse and even joystick actions to your game, but let's stay with keyboard events for now.
Since Godot Editor is basically a game made using the Godot classes, you can even access this class in a more visual way within your project settings:
Keyboard events are handled by the InputEventKey class, this is very important to know before we dig into the code itself, since it will allow us to filter events we won't want to handle.
Every node in Godot is able to handle inputs, they are handled differently depending on the Node, but they all have the ability to listen to input events.
By overriding the _input(event) callback you can manage how these events will be handled.
Clearing default events
If you already have default values for your actions, you will need to make sure they are cleared when the player adds another binding, this will make sure you don't have duplicate events leading to the same action. So, how do we do this? Well, it's very easy, you just need to
lose three hours trying to figure out how to erase an event get the list of events attached to an action, then remove them from this list. Let's go to GDScript.
The InputMap class offers a method that erases a given input event from a given action. What we are doing here is running through all the associated events in the said action and erasing every single of these events by using another method that returns an array of events bound to this action.
Filtering what we want
Since in the case of we will only use keyboard events, we are basically saying: "hey if we are not handling a keyboard event, there's nothing else to see here".
Using return does basically that, it finishes a functions and...returns from the given logic branch, you can also return with a value, but this is not the case here.
Finally what we want
After that we can finally handle what we want, and to this we will use a method that checks for the action which the event may be associated with, but we will test if the event isn't bound to that action, because if it does we don't need to do anything.
Then we simply tell Godot to use the clear_method() we just created, and then we assign a new event to that action. Also you can see that I'm exporting a string variable to the editor, so that we can make a button that knows which action it should work with, and we can reuse this code later.
The ! sign invert the statement, meaning it shall test for the opposite of what we are stating, is the same as the not keyword. I know I need to be more consistent and I should use only one of them... sorry syntax standards I've failed you.
After that you can tell the Node to, by default, start with the _input process turned off, so that it will wait for a trigger to start the process. Also you can tell it to turn off after binding the key, so it will bind only once.
After that you can use any kind of trigger to bind your key to an action. One that I found really useful is the button_up, you connect it to the set_process_input passing an extra bool argument with true as its value and there you will have it.
Also, if you want to give a feedback to the player of which key is being bound, you can translate an event to an string and use it as the text of a label in your interface.
That's it, keep developing and until the next time!