Thanks to visit codestin.com
Credit goes to github.com

Skip to content

arycama/PhysicsMoveTowards

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Physically-based move towards.

This contains an easing/interpolation/damping/whatever else you want to call it function that is based on physical acceleration and deceleration.

It simply takes a current, target, acceleration and deltaTime value, and will move the current value towards the target. The formula is physically plausible, objects can not exceed their max acceleration. It correctly handles undershoot and overshoot cases and thus requires no clamping or epsilon checks outside of the function. It can be used as a drop-in replacement for other damping/easing functions.

Compared to other common functions, it has the following advantages.

Lerp(current, target, deltaTime * speed): One of the most commonly (mis)used damping functions, this will speed up almost instantaneously, but will progressively slow down as it converges to the target. It essentially moves halfway every frame, only ever reaching the target when the distance becomes so tiny that floating point errors cause it to land. While better than nothing, lerp essentially has an instant, unrealistic amount of acceleration, and then a continuously decreasing amount of acceleration as it tries to reach the target. Changing the target partway through will result in an instant flip in velocity which looks unnatural. There are also deltaTime-dependencies which can severely affect the output based on the simulation rate.

MoveTowards(current, target, deltaTime * speed): This is a simple linear movement from one point to another. It has no easing, or acceleration. Or rather, in physical terms, it represents an extremely high initial acceleration impulse to reach a velocity in a single frame, and then 'coasts' for it's duration until it reaches the target, and then applies a large amount of instant deceleration. While simple, it does not look natural and can appear 'slower' since our eyes interpret things that are accelerating/decelerating as faster and more interesting/exciting than something moving at a constant velocity. This also doesn't handle direction/target changes gracefully, it will instantly flip and change directions, which is rather unnatural and jarring.

Smoothdamp(current, target, ref velocity, smoothTime): This can be useful to add some amount of natural-looking acceleration/deceleration moving between targets. Since it tracks a velocity value, it has some sense of it's previous state and can naturally speed up/slow down over different values. However it is parameterised in terms of 'smooth time' and the inner workings aren't overly intuitive or understandable.

PhysicsMoveTowards(current, target, ref velocity, acceleration): Finally, this new function can be physically represented as constant acceleration, followed by constant deceleration. While a simple concept, handling overshooting, halfway points, and numerical issues can be a challenge. By correctly detecting and compensating for these, a robust formula can be applied to a wide range of situations. Since it uses a physically-meaningful acceleration and velocity parameter, it has a clear physical meaning and basis behind it, and can be used for a wide range of natural behaviours. Changing the target partway through will result in a natural deceleration and then acceleration in the opposite direction, followed by a 2nd deceleration to arrive at the target with 0 final velocity.

It is important to understand that the goal of PhysicsMoveTowards isn't to ever avoid overshoot, as this is not physically possible with a fixed acceleration value. However, this will only ever occur if the range between minimum and maximum values is sufficiently decreased while the object is already moving, as this may create a situation where even instant deceleration will result in overshoot, unless the max acceleration limit is ignored, which is against what this function aims to achieve. As long as the range between minimum and maximum target values remains fixed, or increases, overshoot will not occur. If you need guaranteed no overshoot, you will need to use a different function.

It is likely possible to derive a version of this function which takes a target acceleration value, but is able to ignore the limit when an overshoot situation is detected, however that is not how this function is intended to be used.

One further note, while this functionality is desirable for physics-based objects using rigidbodies and forces, it will unfortunately not produce the correct amount of acceleration/deceleration. This is because of how discrete physics works, the relationship between velocity and position is not the same as continuous, so the formula needs to be modified for discrete physics to be accurate. Currently an equation that simply solves for acceleration is provided, which will slightly undershoot, however based on timestep and range this may not matter. An updated equation may be added in the future.

One other interesting situation would be to accelerate to an arbitrary 2D or 3D target by combining this equation on multiple axes. While an easy solution may be to apply the 1D formula in a straight line to the target, this does not work for overshoot cases where the direction changes. Solving this requires finding solutions to 2 or 3 travelTime equations so that the acceleration can be evenly distributed between them while ensuring the magnitude of the acceleration is equal to the max acceleration. I have not been able to find a closed form solution for this yet.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages