A good way to get the speed of an object

What is a good way to get the speed of an object?

I thought you could just measure the distance it moved during a frame and divide with delta time. But that creates a completely unreliable number that jumps wildly and strangely enough seems to change based on the framerate.
Then I tried to do the same but over a fixed real time. The result is much better but it stills jump around a bit.

So what can I do to get it even better? I want to use this value for movement so I can’t sample over a too long of a time.

That should be a little jittery but not too bad… what would make it VERY jittery is if the object is being moved a fixed amount per frame, rather than being moved an amount proportional to Time.deltaTime. How is the object being moved?

You can always just use something like Lerp to make a poor-man’s low-pass filter and choose whatever coefficient you want to get the required lack of jitter:

https://discussions.unity.com/t/807121/2

Obviously the more smoothing you do the more laggy the input is, the less smoothing you do the noisier the input is.

@Kurt-Dekker I actually tried to use a Lerp going from 0 to theoretical max units per second and using the current speed as the % amount of the Lerp. But since it was so jittery you could imagine how that turned out. The acceleration was based on a fixed value multiplied by delta time, but as the framerate increases this value would not be high enough to go over the jitter, meaning the higher the framerate, the slower you moved.
This happens every frame and the final value is set to a V3 that pushes the object using impulse force. This force is set to repeat every frame. (no there’s no code, it’s done in Playmaker)

Are you doing it in update or in fixedUpdate? When doing it in fixedUpdate and divide by Delta time you get a wrong result.

1 Like

That is an EXCELLENT point mabulous… a FixedUpdate() (physics object) would move an identical amount of distance each frame, but then if you divide by Time.deltaTime (which varies wildly) outside of that, it would be very jittery.

Here is some timing diagram help explaining the above:

https://docs.unity3d.com/Manual/ExecutionOrder.html

@mabulous @Kurt-Dekker Thanks guys but it did not matter. If you set it to update, both get position and get delta time and then calculate, it’s the same jitter. If you however do this with a fixed interval it gets even worse and also becomes frame dependent.

What kind of object do you try to get the velocity of? How is it’s motion controlled? if it is a physics controlled rigidbody, you should use the rigidbody.velocity property

@mabulous It’s rigidbody but I can’t use velocity. I don’t want any of the physics to affect the object, like gravity, friction, inertia etc. I only want to make sure it doesn’t clip into other objects, that’s why I use rigidbody. So I use a hacky way to set velocity to 0 every frame, and so far it’s caused no problems.
But why does it matter? I measure the distance it moved from one frame to an other. It shouldn’t matter the way it moves, either from force, translate or set position.

So I thought it might be some weird thing with Playmaker so I made a simple script. But it didn’t change anything, low FPS gives a high speed and high FPS gives almost no speed. What am I doing wrong?

This is the script I placed on the object.

using UnityEngine;

public class GetSpeed : MonoBehaviour
{
    private Vector3 pos = new Vector3(0f,0f,0f);
    private Vector3 old_pos = new Vector3(0f, 0f, 0f);
    private float dis;
    public float speed;
    void Start()
    {
        pos = transform.position;
    }

  
    void Update()
    {
        old_pos = pos;
        pos = transform.position;
        dis = Vector3.Distance(pos, old_pos);
        speed = dis / Time.deltaTime;
    }
}

Well there’s your problem.

So you mean the code above can somehow detect that the object has a rigidbody that has its velocity set to 0 and give a result that differs depending on framerate? Amazing if that’s the case. It does not matter what object I place it on or the method it moves. The object moves fine.
Also, you where not correct about doing this in update. It should be in fixed update. The same code went from giving completely wrong info while also being framerate dependent to giving an almost perfect value at any framerate with this small change.

obviously, since rigidbodies get updated in fixedUpdate by the Unity engine.