In Unreal Engine 4 we wanted to make binding input events as easy as possible. To that end, we created Input Action and Axis Mappings. While it is certainly valid to bind keys directly to events, I hope I can convince you that using mappings will be the most flexible and convenient way to set up your input.
So what are Action and Axis Mappings?
Action and Axis Mappings provide a mechanism to conveniently map keys and axes to input behaviors by inserting a layer of indirection between the input behavior and the keys that invoke it. Action Mappings are for key presses and releases, while Axis Mappings allow for inputs that have a continuous range.
Why would I want to use a mapping instead of binding directly to the key?
Using input mappings gives you the ability to map multiple keys to the same behavior with a single binding. It also makes remapping which keys are mapped to the behavior easy, both at a project level if you change your mind about default settings, and for a user in a key binding UI. Finally, using input mappings allows you to interpret input keys that aren’t an axis input (e.g. gamepad thumbstick axes which have a range of [-1,1]) as components of an axis (e.g. W/S for forward and back in typical FPS controls).
Alright, these sound great. How do I set them up?
In the Input section of Engine Project Settings you can see the list of existing mappings and create new ones.
Actions are pretty straightforward: give the action a name, add the keys you want mapped to the action, and specify which modifier keys need to be held when the key is pressed. Axis mappings are also reasonably straightforward. Instead of specifying any modifier keys, however, you specify a Scale. The Scale is a multiplier on the value of the key when summing up the Axis’ value. This is particularly useful for creating an axis out of keyboard keys (for example, W can represent pressing up on the gamepad stick while S represents pressing down).
Now that I’ve defined some mappings, how do I use these things?
Mappings can be bound to behaviors from both Blueprints and C++.
In C++ you will most typically set up your bindings in the Pawn/Character::SetupPlayerInputComponent or PlayerCharacter::SetupInputComponent functions; however, anywhere you have an InputComponent is valid. The bindings are formed by calling BindAction/Axis on the InputComponent.
InputComponent->BindAxis("MoveForward", this, &ASampleCharacter::MoveForward);
InputComponent->BindAction("Fire", IE_Pressed, this, &ASampleCharacter::OnBeginFire);
InputComponent->BindAction("Fire", IE_Released, this, &ASampleCharacter::OnEndFire);
In Blueprints you can place an Axis or Action Event node from the Input section of the context menu or palette of any Actor blueprint.
In both C++ and Blueprints, Axis events will fire every frame passing the current value of the Axis while Action events will have the Pressed and Released outputs fire as the key(s) are pressed.
An Axis’ value is the sum of the values of each key’s state in that frame. So in the MoveForward case pictured above, if you have only W held down the Axis’ value is 1, but if you had both W and S held down then the Axis’ value would be 0. It should also be noted that if you had both W and Up pressed then the value is 2, so you would likely want to clamp the value in the bound function.
Actions that are bound only to a pressed or released event will fire every time any key that is mapped to it is pressed/released. However, in the case of Paired Actions (actions that have both a pressed and a released function bound to them) we consider the first key to be pressed to have captured the action. Once a key has captured the action the other bound keys’ press and release events will be ignored until the capturing key has been released.
Is that all?
There are a lot of other important input concepts (some of which are covered in the input documentation) such as the input stack, which Actors have input enabled by default and how to enable input for other Actors, and how input consumption works, but we’ll leave diving in to those for another post.
I hope I’ve convinced you that using Action and Axis Mappings will be the best way to set up input in your project, but if not, that’s fine! You can always bind directly to Keys if that’s easier for you and convert to using Actions and Axes when they provide value for you.
Have questions? Don’t forget you can join us over in the forums – we’re always happy to help!