- Home /
Custom Acceleration
Hello, i've gotten a project in which i have to simulate a movement with acceleration, constant speed and deceleration. Basically, the user clicks somewhere on the screen, if raycast says it collides somewhere on the floor move character there. The problem is the move, i have a beginDistance and endDistance variables which represent the distance (no specific unit) where i apply acceleration or deceleration.
Basic acceleration equations are :
a = (Vmax - Vinit) / t
d = ((Vmax + Vinit) * t) / 2
where
a = acceleration
d = distance
t = time
Vmax = maximum velocity
Vinit = initial velocity (always 0 in this script)
which gave me this for acceleration :
float smoothDist;
smoothTime += Time.deltaTime;
smoothDist = Vector3.Distance(beginPos, nextPos);
float totTime = ((2 * smoothDist) / (movementSpeed + 0));
if (smoothDist < Vector3.Distance(transform.position, nextPos))
transform.position = Vector3.Lerp(beginPos, nextPos, ((totTime * smoothTime) / 100));
beginPos = position where acceleration begins
nextPos = position where acceleration ends (this method has 3 parts)
In short, in this version i try to calculate how much time is needed to end the acceleration part, then just move transform to the corresponding % of the distance. Which works, but there's no acceleration. After trying different ways of using the equations, i'm out of ideas. Does anyone know how to do this?
Answer by WillTAtl · Dec 06, 2011 at 03:13 PM
Several ways to do this. SmoothDamp might be the easiest, as it acts like Lerp but accelerates rather than using a constant speed. If you're using rigidbodies, you could also do this by using AddForce, though you'd need to deal with the three states, accelerating to speed, cruising at speed, and decelerating back down to stop, and also remember the edge case where the trip is too short to ever reach the cruising speed!
Hi, actually, i'm not using rigidbodies, and probably will not ever. Depends on what they ask me to code. But at the moment i'm not. Also, SmoothDamp seems interesting but is it possible to make it reach cruising speed over a deter$$anonymous$$ed distance? Beacause if it does the reverse of the Lerp, then i'd have to calculate the distance for it not to go over the cruising speed, but that's nto what was asked of me. I have to leave a public float that will be the distance used for acceleration/deceleration. So i have to not go over it while reaching cruising speed.
that's ... a very odd-see$$anonymous$$g requirement to me. Accelerating from 0 to some speed, over some specified distance... I'm pretty sure you're not guaranteed a constant acceleration exists that would meet both of those goals for all cases! Certainly if distance were too long or the cruising speed too low, you could have to go faster than cruising speed and then hit the breaks to slow back down to cruising speed when you reach the specified acceleration distance!
Actually, it doesn't have to behave like a real life moving mass. The point is to have it reach a certain speed over a distance. I think using an example would be wise so :
The demo i'm using to test the script, i have a 500x500 plane. The script is atached to the camera, and is supposed to make the camera move where i click with the mouse on the plane. I choose 100 to be the accelerating and decelerating distance and the cruising speed of 50 units per second.
In this demo, if the camera is in one corner, and i click on the opposite corner (following the diagonal), the distance to move is around 707. The acceleration/deceleration distances are good. So, begining with a velocity of 0u/s i should reach a velocity of 50u/s by the time i reach the distance of 100 units. Then i'd move at 50u/s till i reach the last 100 units, then begining at 50u/s i'd gradually slow down till 0u/s at the arrival point.
Still in the example, with the equation d = ((Vmax + Vinit)*t) / 2, i know it'd take around 4 seconds to reach the maximum speed while accelerating (t = (2*d) / (Vmax + Vinit)).
$$anonymous$$y problem is, how do i calculate where the moving object should be at time T while accelerating or decelerating?
After a change in basic data and many trial and error tries (i was thinking too complex when it was really simple), i got to this :
d = (((((Vmax - Vinit) (Tx / Tmax)) + Vinit) Tx) / 2);
d = distance
Vmax = max velocity
Vinit = intial velocity
Tmax = maxmum acceleration time
Tx = current time
What this does is it gives the current distance at time Tx. Which is what i wanted, although i had to abandon the idea to limit it to a given distance, but ins$$anonymous$$d limit it in time.
well, if you solve for an acceleration value, you can use it to increase velocity every fixedUpdate. If you're not using rigidbodies, you can just make your own velocity vector, then after updating it, multiply by deltaTime and add it to position. You could also use lerp on your velocity variable if you solved for the time it would take to accelerate, first to accelerate and then to stop again.