This site uses strictly necessary cookies. More Information

X- Home /

**Question**by 1337keegan · Nov 29, 2018 at 10:40 PM · controllervelocitymovement scriptplayer movementacceleration

# (C#) Accelerating Player Based On Distance

Hello, I've been stuck working on this code for a few days now and I've made some progress but am totally stumped.

The scenario: A direction is pressed and the player accelerates linearly from 0 to a speed of lets say 3u/s and hits that speed within 0.5 units distance. The time it takes to accelerate is irrelevant.

I understand that the first thing i have to do is calculate the acceleration, which i've found multiple contradicting formulas for, and then increment the player's position based on that acceleration. Would I also have to calculate how long that would take in order to move the player properly? I've looked extensively into lerps and simply can't figure out a solution. Any help is welcome at this point. Thank you!

**Answer** by Eno-Khaon
·
Nov 30, 2018 at 10:54 AM

This is where a **good reference point** can really come in handy.

By a typical acceleration formula, you're taking the *current speed*, the *target speed*, and the time spent accelerating between those two speeds. With that information, you can determine the distance traveled and the rate of acceleration to reach that point.

This is done using the formulas:

^{tgtSpeed-curSpeed}/_{time}= acceleration(

^{avgSpeed}/_{2})*time = distance

Since you know the distance, however, let's take this equation and work backwards, shall we?

^{distance}/_{avgSpeed}= time

**Yep, time still winds up being a valuable factor in this.**But since the time can be determined by reversing the

*speed-to-distance*equation, you can use that to turn it back around and calculate the acceleration rate (force) to apply to reach the desired speed.

```
public static float AccelerateToTarget(float currentSpeed, float targetSpeed, float distance)
{
float averageSpeed = (currentSpeed + targetSpeed) * 0.5f;
float time = distance / averageSpeed;
float speedDifference = targetSpeed - currentSpeed;
float acceleration = speedDifference / time;
return acceleration;
}
float forceToAdd;
void Start()
{
Rigidbody rb = GetComponent<Rigidbody>();
// Example call using your values
forceToAdd = AccelerateToTarget(rb.velocity.magnitude, 3.0f, 0.5f);
}
void FixedUpdate()
{
rb.AddForce(transform.forward * forceToAdd);
}
```

Granted, this example won't stop accelerating after it reaches that speed after that time, but it will reach the target speed of 3u/s upon traveling 0.5 units *(not counting applicable approximation errors and friction)*.

**Answer** by 1337keegan
·
Nov 30, 2018 at 04:37 PM

That's excellent, thank you! However is there a way to do this positionally rather than through force? my object isn't a rigidbody, it's a 2D sprite and I would like to manipulate it through transform.position if at all possible.

Position is calculated by the physics engine(s) **about like this**:

```
// Written on a 2D basis
void FixedUpdate()
{
Vector2 velocityPerFrame = lastFrameVelocity + (acceleration * Time.fixedDeltaTime);
Vector2 positionPerFrame += velocityPerFrame * Time.fixedDeltaTime;
}
```

With that in mind, that's also the general means of replacement. The *AccelerateToTarget()* example I gave (when multiplied by a normalized movement Vector) would be the force to add per frame (multiplied by Time.deltaTime or the like) to the current velocity.

You may also want to take a look at the answer @Bunny83 gave to **this question** to help smooth out the acceleration applied.

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.