There are two problems. One, you are setting the velocity directly yet applying it as a force by taking into account the ridged body mass. Two, your "slowing down" is exactly the same as you are speeding up, you are not inverting the speed adjustment.
Though I am unsure why (if the object has a ridged body) you are performing this by hand instead of with physics forces, may I suggest:
You effectively need to answer two questions at any given time, with one more optional questions.
- How far will it take me to stop?
- How far is my target?
- Optional: How much more distance can I accelerate until I would be unable to decelerate in time.
To stop we'd the time for our velocity to decelerate to zero:
- Let v be the current velocity and v' the velocity in time t. 0=(v - v') or v' = v
- Then letting a be acceleration a*t = v or t = v/a
We then need the distance this takes us:
- First calculate the average velocity A A= (v+v')/2 or A= v/2
- Then the stopping distance d is a matter of applying time to the average velocity d = tA or d = tv/2 or d = (v/a)v/2
The code is as follows
protected virtual void Movement(){
targetDistance= Vector3.Distance(transform.position, wantedPos);
stoppingDistance = GetCurrentStoppingDistance(Velocity.magnitude, acceleration);
public Vector3 engineVelocity = transform.forward * acceleration; //assume we are accelerating forward at first
if(targetDistance<= stoppingDistance ){
engineVelocity = -1 * engineVelocity; //decelerate instead;
}
else if(targetDistance<= (stoppingDistance * 1.05) ){
engineVelocity = Vector3.zero; //stop accelerating 5% of the distance before we need to start slowing to avoid over shoots between frames
}
/*
* set the velocity as a velocity (no mass adjustment needed, this isn't a force being applied.
* Note we SHOULD be using the ridged body ApplyForce and supply it with a VelocityChange force
* type instead)
*/
Velocity += engineVelocity;
}
private float GetCurrentStoppingDistance(float velocity, float accelerationPossible){
return (velocity/acceleration) * velocity * 0.5f;
}
Remember: Velocity changes do not take mass into consideration, only application of a force or an impulse would require that.
distanceToComeToStop = (speed*speed)/(2*maxAccel)
– House May 17 '13 at 17:36