- Home /
Why is keyboard faster than gamepad?
When I use the gamepad/joystick, the character moves correctly, at expected velocity. When I use the keyboard, it's ok only when I press one key at a time, but...
Once I press the keys down + left, or up + right, for example, the character moves much faster than normal.
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0, moveVertical);
rigidbody.AddForce (movement * speed * Time.deltaTime, ForceMode.VelocityChange);
Any clues as to what could be causing this unwanted speed?
Again, the gamepad works perfectly for some reason, only the keyboard causes this error. I imagine someone may have encountered this also as it is based on the Roll-A-Ball tutorial project. Thank you for any ideas on this.
Have you tried Debug.Log()ING out the values of moveVertical and horizontal? Could it BE that on the keyboard they both go to "1" resulting in a vector length of sqrt(2), ins$$anonymous$$d of 1 ? $$anonymous$$aybe with the gamepad the values get naturally clamped.
You might need to normalize your movement vector.
Ok, so Debug.Log'ing moveHorizontal and vertical yeilds what you'd expect -- a value from -1 to 1. As does outputting the Vector movement. Everything is normalised already.
However, if you output rigidbody.velocity, that is when you see the values are different from keyboard to gamepad.
Note, "GetAxis" is used to capture both keyboard and gamepad input. So you'd think the results would be consistent, but they're not.
If you add that script to a sphere, you'll see the problem. I've found another question like this one, but no answer to what's causing this.
Aha, so I went ahead and tried "movement = movement.normalised" and it sort of helped. However it came at the cost of having the analog pressure sensitivity of the joystick. And there is also a strange behavior when you release and keys, the ball rolls to a strange stop. I'll keep tinkering. Thank you for pointing me in a helpful direction though.
Answer by SethSR · Jun 19, 2014 at 06:55 AM
When adding forces, you are using the vectors magnitude in the physics calculations. With 3-dimensional vectors, magnitude is calculated with:
M = sqrt( x*x + y*y + z*z);
This means if you hold "up" on the gamepad or press "W" on the keyboard, you get Vector3(0, 0, 1)
, and a magnitude of sqrt(1 + 0 + 0)
or 1. If you hold two directions however, such as down and right, you get Vector3(-1, 0, 1)
and a magnitude of sqrt(1 + 0 + 1)
or about 1.41. This is what gets used in the force update, and this is where the extra speed is coming from.
As for why you only get the error with your keyboard, it may have something to do with the physical build of your gamepad, or how it calculates the numeric values for the corners. Normally, this would be an issue with the keyboard and the gamepade, but your gamepad might not return full upper values (1.0F) for both X and Y when in a corner.
Plus, you don't just want to normalize the vector, because normalizing creates a "unit vector", a vector with any direction, but a magnitude of only 1. As you just want to limit the magnitude to 1, Vector3.ClampMagnitude() is indeed the correct choice here.
Quick correction, normalising creates a vector with a magnitude of exactly 1. Clamping will create a vector with a maximum magnitude of 1 (or whatever you set it to).
In both cases the direction of the vector is identical to the direction of the original vector.
Answer by Andres-Fernandez · Jun 06, 2014 at 06:34 AM
I'm not sure but it could be a matter of vector magnitude. Gamepad always gives you the same vaue when max tilted, no matter the direction, while two perpendicular vectors added gives you a vector with a higher magnitude than its two components. If you normalize the vector you get from the keyboard input, you'll get same value for any direction.
Like I wrote above to Nosekills, I've Debug.Log'd moveHorizontal and vertical and it's what you'd expect -- a value from -1 to 1. As does outputting the Vector movement. Everything is normalised already.
However, if you output rigidbody.velocity, that is when you see the values are different from keyboard to gamepad.
Note, "GetAxis" is used to capture both keyboard and gamepad input. So you'd think the results would be consistent, but they're not.
If you add that script to a sphere, you'll see the problem. I've found another question like this one, but no answer to what's causing this.
I imagine this is an easy fix, but I have no clue. Please help!
I don't know if this will help, but it's recommended that all physics updates should be done in FixedUpdate ins$$anonymous$$d of regular Update so they stay in step with the physics engine. When you change the velocity of an RB that may be affecting some weird thing.
Using "movement = movement.normalised" sort of helped, but caused other unwanted behavior I'll try to fix. Thanks for the tip!
Answer by blueLED · Jun 07, 2014 at 05:01 AM
In case this helps anyone else:
movement = Vector3.ClampMagnitude(movement, 1.0f)
Setting it this way seems to have better results than normalising so far (keeps sensitivity of joystick).
Your answer
![](https://koobas.hobune.stream/wayback/20220613150918im_/https://answers.unity.com/themes/thub/images/avi.jpg)