Help calculating accurate VectorForce to reach a position in duration
Hi everyone,
I’m trying to move a part from point A to point B using a VectorForce in Roblox, and I want it to reach the target position in exactly 0.1 seconds, with gravity enabled.
Here’s what I’m doing:
The part starts at rest.
I calculate the displacement (target.Position - part.Position).
I use the following formula for force:
local displacement = target.Position - part.Position
local duration = 0.1
local gravity = Vector3.new(0, -workspace.Gravity, 0)
local requiredAcceleration = (2 * displacement) / (duration ^ 2)
local forceAcceleration = requiredAcceleration - gravity
local force = part.AssemblyMass * forceAcceleration
Then I apply that force using a VectorForce, and destroy it after 0.1 seconds.
The problem: It consistently overshoots the target by quite a lot. The part flies well past where it’s supposed to land.
What I’m Looking For:
Is my formula wrong, or am I misunderstanding how VectorForce accumulates motion over time?
Is there a better way to calculate the force needed to precisely reach a target in a short time, while accounting for gravity?
I don’t want to use ApplyImpulse, since I specifically need the behavior of VectorForce.
I tested your code with a longer duration value (10 seconds), and the part reached the target at 10 seconds.
A few things to note:
The part will not move linearly towards the target - it will travel slowly at first, accelerating over time.
When the VectorForce is disabled, the part still has leftover velocity. If the velocity is high, the part might continue to travel a long ways past the target. This is especially true with small values of duration, like 0.1.
@TheMario_1’s solution may be a good idea depending on what you’re trying to do here.
Your formula is not wrong, I have used it before for my character controller for hipheight.
It works for this case as there is an opposing force which is gravity which balances it out in the end.
Also I implemented physics substepping to handle low fps scenarios.
Also my force is updated every frame as the displacement variable changes over time.
If you are using task.wait(0.1) it might wait 0.1 seconds plus an additional frame 1/60 which messes up the calculation furthermore.
-- counter gravity and then solve constant acceleration eq
-- (x1 = x0 + v*t + 0.5*a*t*t) for a to aproach target height over time
local t = POP_TIME
aUp = Workspace.Gravity + 2*((targetHeight - currentHeight) - currentVelocity.Y*t)/(t*t)
I would recommend @TheMario_1 solution instead unless you want to add in additional forces.
Here is some data and a nice graph to help adjust the responsiveness property to avoid overshoot while also calculating the time taken to reach the goal.