landings
landings

Reputation: 770

How to calculate a GameObject's speed in Unity?

I have tried something like

float speed = (currentPosition - previousPosition).magnitude / Time.deltaTime

in Update().

But I get very bad results because currentPosition and previousPosition are too close. After subtraction there's too much rounding error. The speed values fluctuate too much.

And also I don't want to average across multiple frames because that produces delays and only improves the result a little.

Is there any better way to calculate the speed of an object?

Upvotes: 3

Views: 4043

Answers (1)

Immersive
Immersive

Reputation: 1704

You could use a coroutine that calculates the speed slower than every frame:

void OnEnabled() {
    StartCoroutine(SpeedReckoner());
}

public float Speed;
public float UpdateDelay;

private IEnumerator SpeedReckoner() {

    YieldInstruction timedWait = new WaitForSeconds(UpdateDelay);
    Vector3 lastPosition = transform.position;
    float lastTimestamp = Time.time;

    while (enabled) {
        yield return timedWait;

        var deltaPosition = (transform.position - lastPosition).magnitude;
        var deltaTime = Time.time - lastTimestamp;

        if (Mathf.Approximately(deltaPosition, 0f)) // Clean up "near-zero" displacement
            deltaPosition = 0f;

        Speed = deltaPosition / deltaTime;


        lastPosition = transform.position;
        lastTimestamp = Time.time;
    }
}

Upvotes: 4

Related Questions