Fo’ Swizzle: Enhance Input Movement Setup
September 29, 2024It isn’t often I need to create characters and setup their movement. It’s usually something I do in a gamejam, and tend to just find an example I’ve done before and try not to think too much about it. However, there’s always been some quirkiness to it that I’ve often felt I didn’t fully understand. So I wanted to take a little time to fully think about three topics:
- Which axis is “Forward” in Unreal?
- With enhanced input, why do we need to swizzle?
- Do we need to rotate something 90 degrees?
I know from previous understanding that X is considered “forwards” in Unreal Engine, though its a little confusing depending on what you’re familiar with regarding X and Y. In 2D plotting, you imagine X being “left and right” and Y being “up and down”. However, in Unreal, the X and Y directions are flipped somewhat.
Let’s look at a setup of creating character movement controls using the Enhanced Input plugin.
On the whole it’s not hugely different from the old input mapping setup Unreal used. However, there’s two confusing aspects:
- What is swizzling and why do we need it?
- The conflict between controller X and Y axis vs Unreal’s X and Y axis
The way I’ve made sense of it is as follows:
- When polled, the Gamepad Left Thumbstick X-Axis (left and right on stick) will just return a vector value between -1,0,0 and 1,0,0 (based on how much you’ve moved it).
- When polled, the Gamepad Right Thumbstick Y-Axis (up and down on stick) will similarly just return a vector value between –1,0,0 and 1,0,0. So despite being on a different axis, it returns the same range of values as the X axis.
- In our game logic where we process the input (see code picture below) we expect forwards / backwards to be on the input vector’s first value (X) (because in Unreal X is forwards) and we expect left / right to be in the input vector’s second value (Y).
- Because of this, when our stick’s Y axis is mapped to the first value (X) in our input vector, it doesn’t need to be “swizzled”.
- However, we want our stick’s X axis it to be mapped to the second value (Y) in our input vector, since left and right is Y in unreal. By adding the Swizzle modifier, it converts an input such as like (1,0,0) to (0,1,0).
This is similar with WASD, but less confusing than the thumb sticks because keys don’t have their own X and Y axis to muddy the waters.
- W is forward, so we want it to be (1,0,0) – so we don’t need to modify it.
- D is right, we want it to represent (0,1,0) – so we need to swizzle it to change the (1,0,0) to (0,1,0).
- A and D are setup similar but have the negation modifier. This is needed since key inputs can only represent 0 to 1, where as thumb sticks can represent -1 to +1.
Ultimately, by the time the input gets to ProcessInputMovement(...)
, when we call Instance.GetValue()
we’ll get the input in the form of a 2d vector. During the engine’s input polling, it’ll be polling all of the keys we’ve mapped inside of IA_Move within our InputMappingContext and pushing their values into a 2d vector (it does this as we set the Value Type in the IA_Move InputAction to be Vector2D). The swizzling we did earlier just lets us write to the second (Y) value of the vector we’re building, so our ProcessInputMovement(...)
can perform movement based on the first (X) and second (Y) values of the vector.
To close, the question I had around “needing to rotate things by 90” is actually quite an isolated quirk. It seems to only affect the facing direction of your mesh relative to the forward vector of the controller / character. As a result, you may need to rotate your character’s mesh by 90 degrees. Alternatively, character models should have their forward dimension facing in the direction of the positive X-Axis.