iPhone - How to calculate a decent touch swipe speed?

I'm tracking the touch positions in an update function and am trying to take a measure of the speed of a swipe being performed. At the moment i'm only taking the last frame's touch position change and using this to extrapolate out using Time.deltaTime to get a rough speed of that motion.

I guess i should really be averaging it more than just taking the last frame but i figured it'd at least be ok.

What i'm seeing though seems to be some frames coming through with 0 movement even though the motion is relatively constant speed.

What's going on? Is it because the touches are updated at a certain frequency and the game (at the moment in the simulator and via unity remote) is getting its update frames at a different frequency causing some updates to have not received new touches?

Is there a better callback i can be using that is just updated on touch updates?


The method you are using is reasonable up to a point. The problems tend to occur if the frame rate is TOO good. You won't see exact pixel movements of 1 or 2 pixels; they tend to get rounded to 0 or 5 pixels. So a tiny movement over a very small deltaTime can be rounded into a 5-pixel movement. When you divide to calculate the velocity, you end up with an absolutely enormous velocity!

A cheap solution is to ignore deltas of less than 10 pixels. That seems to work fine on all the devices I've tested it on, including retina displays. That would probably work for you as well, especially given that you seem to be interested in swipes, not small drags.

To solve your original problem, you could also ignore frames where the movement was 0. But that depends in part on what you are using the velocity for. In my case I wanted to calculate the velocity only when the drag ended. If you need the velocity recalculated throughout the drag you'll probably have to store the last N delta movements and times, and calculate a running average. You'll have to play with different values of N to see what works for your app.

You can use exponential smoothing on the velocity.
smoothVelocity = alpha * currentVelocity + (1-alpha) * previousSmoothVelocity
To calibrate alpha, set it between 0 and 1, 1 being no smoothing.
I would estimate something like 0.7.