So I am attempting to create a program that uses a doom-style acceleration, but when it decelerates, it never hits zero and always bounces around it. Here is my code:
float minSpeed = 0;
public float maxSpeed = 10;
public float currentSpeedX;
public float currentSpeedY;
public float accelerationPerSecond;
public float decelerationPerSecond;
void Update()
{
// Horizonal Acceleration
if (Input.GetAxisRaw("Horizontal") == 1 && currentSpeedX < maxSpeed)
{
currentSpeedX += accelerationPerSecond * Time.deltaTime;
} else if (Input.GetAxisRaw("Horizontal") == -1 && currentSpeedX > -maxSpeed)
{
currentSpeedX -= accelerationPerSecond * Time.deltaTime;
} else if (Input.GetAxisRaw("Horizontal") == 0)
{
if (currentSpeedX > 0)
{
currentSpeedX -= decelerationPerSecond * Time.deltaTime;
} else if (currentSpeedX < 0)
{
currentSpeedX += decelerationPerSecond * Time.deltaTime;
}
}
transform.Translate(Time.deltaTime * currentSpeedX, 0f, Time.deltaTime * currentSpeedY);
}
KevRev
April 18, 2019, 4:32pm
3
I think its because at some point, the amount you want to decrease it by is larger than whats left, causing it to flip/flop over 0.
Try this:
float minSpeed = 0;
public float maxSpeed = 10;
public float currentSpeedX;
public float currentSpeedY;
public float accelerationPerSecond;
public float decelerationPerSecond;
void Update()
{
// Horizonal Acceleration
if (Input.GetAxisRaw("Horizontal") == 1 && currentSpeedX < maxSpeed)
{
currentSpeedX += accelerationPerSecond * Time.deltaTime;
}
else if (Input.GetAxisRaw("Horizontal") == -1 && currentSpeedX > -maxSpeed)
{
currentSpeedX -= accelerationPerSecond * Time.deltaTime;
}
else if (Input.GetAxisRaw("Horizontal") == 0)
{
if (currentSpeedX > 0)
{
// Is the amount you are about to decrease by, larger than current value? yes:Set to 0, no: reduce by deceleration
currentSpeedX <= decelerationPerSecond * Time.deltaTime ? currentSpeedX = 0 : currentSpeedX -= decelerationPerSecond * Time.deltaTime;
}
else if (currentSpeedX < 0)
{
// Is the amount you are about to decrease by, larger than current value? yes:Set to 0, no: reduce by deceleration
currentSpeedX >= -(decelerationPerSecond * Time.deltaTime) ? currentSpeedX = 0 : currentSpeedX += decelerationPerSecond * Time.deltaTime;
}
}
transform.Translate(Time.deltaTime * currentSpeedX, 0f, Time.deltaTime * currentSpeedY);
}
try using Mathf.Lerp
else if (Input.GetAxisRaw("Horizontal") == 0)
{
var t = decelerationPerSecond * Time.deltaTime;
currentSpeedX = Mathf.Lerp(currentSpeedX, 0f, t);
}
t is the interpolation value between the two floats, change it to suit your need
I think that’s because you are using Time.deltaTime.
Better use IEnumerators!
Example:
float minSpeed = 0; public float maxSpeed = 10; public float currentSpeedX; public float currentSpeedY; public float accelerationPerSecond; public float decelerationPerSecond;
void Start()
{
StartCoroutine(MoveSpeeds());
}
IEnumerator MoveSpeeds()
{
while(true){
// Horizonal Acceleration
if (Input.GetAxisRaw("Horizontal") == 1 && currentSpeedX < maxSpeed)
{
currentSpeedX += accelerationPerSecond * 0.1f;
} else if (Input.GetAxisRaw("Horizontal") == -1 && currentSpeedX > -maxSpeed)
{
currentSpeedX -= accelerationPerSecond * 0.1f;
} else if (Input.GetAxisRaw("Horizontal") == 0)
{
if (currentSpeedX > 0)
{
currentSpeedX -= decelerationPerSecond * 0.1f;
} else if (currentSpeedX < 0)
{
currentSpeedX += decelerationPerSecond * 0.1f;
}
}
transform.Translate(Time.deltaTime * currentSpeedX, 0f, 0.1f;
yield return new WaitForSeconds(0.1f);
}
}
;)Sorry when there are errors in the code