- Home /
Smooth Acceleration from DPad XBOX Controller
Long story short, the character accelerates smoothly to max speed on keyboard, yet instantly reaches max speed with DPad input from my XBOX Controller. Here is the code:
float hMove = Input.GetAxis("Horizontal");
myRB.velocity = new Vector2(hMove * activeMoveSpeed, myRB.velocity.y);
Floating point increments are done with keyboard input, but with a controller it's immediately skipping all the in between and going straight to one. I'm guessing Unity reading the 6th Joystick Axis (left and right on the DPad) as a button instead of an axis. Tried messing with the gravity and sensitivity in the input manager regarding the horizontal input (6th Joystick axis, "left and right on DPad"), but it still instantly jumps to -1 and 1. I would like for it to smoothly move just like the keyboard input.
Answer by xibanya · Dec 24, 2019 at 09:31 AM
you could code in smooth acceleration so that you can ensure it acts pretty much the same on all input devices..
private const float EPSILON = 0.0001f;
public float accelerationTime = 1;
private float pressTime;
void Update()
{
float hMove = Input.GetAxis("Horizontal");
if (Mathf.Abs(hMove) < EPSILON) hMove = 0;
if (hMove == 0) pressTime = 0;
else if (pressTime < accelerationTime)
{
pressTime += Time.deltaTime;
hMove *= Mathf.Clamp01(pressTime / accelerationTime);
}
myRB.velocity = new Vector2(hMove * activeMoveSpeed, myRB.velocity.y);
}
for proper easing rather than a linear ramp up, you could also do something like this
private const float ACCELERATION_TIME = 1;
private const float EPSILON = 0.0001f;
public AnimationCurve acceleration = AnimationCurve.EaseInOut(0, 0, ACCELERATION_TIME, 1);
private float pressTime;
void Update()
{
float hMove = Input.GetAxis("Horizontal");
if (Mathf.Abs(hMove) < EPSILON) hMove = 0;
if (hMove == 0) pressTime = 0;
else if (pressTime < ACCELERATION_TIME)
{
pressTime += Time.deltaTime;
hMove *= acceleration.Evaluate(pressTime / ACCELERATION_TIME);
}
myRB.velocity = new Vector2(hMove * activeMoveSpeed, myRB.velocity.y);
}
Consider using GetAxisRaw if you want the actual keyboard input and not the smoothed version.
Also this code would be sufficient:
Vector2 velocity = rb.velocity;
float acceleration = active$$anonymous$$oveSpeed / accelerationTime;
velocity.x += Input.GetAxisRaw("Horizontal") * Time.deltaTime * acceleration;
velocity.x = $$anonymous$$ath.clamp(xVelocity, -active$$anonymous$$oveSpeed, active$$anonymous$$oveSpeed);
rb.velocity = velocity;
I copy and pasted the code for the AnimationCurve one and it made my character walk to the right even when I press left.
Never$$anonymous$$d, I just added a multiplication mark in front of:
"h$$anonymous$$ove *= acceleration.Evaluate(pressTime / ACCELERATION_TI$$anonymous$$E);" and it worked fine.
Thank you so much for the help, but I still need help with smooth deceleration when letting go of the axis.
You can do the same thing in reverse, more or less. Set a bool when $$anonymous$$athf.Abs(Input.GetAxisRaw("Horizontal") > 0
as that means it's being held, then when $$anonymous$$athf.Abs(Input.GetAxisRaw("Horizontal") == 0
but the bool is still true, you know that the axis was released. While the bool is true, reduce velocity the same way I posted the acceleration example, except reducing ins$$anonymous$$d of increasing. When you hit zero, set the bool to false. OR, if the axis is not zero again, also set the bool to false. Does that make sense?
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
How would I use Mecanim to holster or draw a weapon? (C#) 1 Answer
Modify Dualshock 4 Controller's lightbar 1 Answer
Flip over an object (smooth transition) 3 Answers