GetAxisRaw with analog stick VS keyboard for diagonal input combination

Hi,

I noticed that when I use UnityEngine.Input.GetAxisRaw for horizontal and vertical axes I get different output depending on analog stick or keyboard, when pressing diagonal input buttons like up-right, down-right and so on

When I use the keyboard I get horizontal of 1 and vertical of 1
When I use analog I get horizontal of 0.5 and vertical of 0.5
When I press up for keyboard I get 1 and also get 1 for up in the analog
So now I have two different speeds when I press a diagonal button for the character. How can I solve that?

Any help is greatly apprecaited!

The value your joystick returns at a corner direction is dependent on the joystick hardware. Most analog joysticks will return 0.7, -0.7 in the up-right diagonal direction. However, this is only the case if the joystick is physically constrained to a circular area. Some old gamepads have square movement areas for the sticks and will return 1.0, -1.0 in the up-right diagonal direction. The keyboard will return 1.0, 1.0 for up-right.

Just process the input vector and constrain it to a circular area like this:

Vector2 moveDirection = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
if(moveDirection.sqrMagnitude > 1.0f) moveDirection.Normalize();

If the magnitude of the vector ever exceeds 1.0, which it would at 1.0, -1.0 or any of the corner directions, it will be normalized. The end result is a circular radius. If keyboard diagonal is pressed, it will return 0.7, 0.7 just like most analog joysticks (with the Y axis flipped of course).

If your joystick is returning 0.5, -0.5 at up-right, that will give you a smaller magnitude and a slower speed than a joystick that returns the proper 0.7, -0.7 vector for a corner. The only way you could handle that is to calibrate the joystick which isn’t directly possible in Unity’s input system. You would need to make a wrapper which would involve a lot of steps. Calibrating the joystick would also involve user interaction and creating a GUI for that.

Out of curiosity, what joystick are you using?

Thank you very much for your detailed response.

I am using xbox 360. Actually it seems to return about 0.7, 0.7, but I am not sure what was the number exactly. I just wanted to say that it is not 1,1.
I actually solved the problem by multiplying the value by 2 then clamping between -1,1 when using the analog stick.
Of course I lost half of sensitivity when pressing righ, left, up, down, but I noticed that other games have full speed half way, so I think most games use this cheap solution.
For the calibration, I think rewired might be able to do that trick, but may be it is an overkill solution.
https://www.assetstore.unity3d.com/en/#!/content/21676

The solution I posted isn’t particularly expensive and lets you have the full range of movement on the joystick.

Well, since this is an Xbox 360 controller and it returns 0.7 at the corner, there’s no need for calibration. As for Rewired, looks very nice! … Oh, I guess I should mention that I’m the author. :stuck_out_tongue: (See my signature?)

3 Likes