Hi,
I’m making a mobile game where the player needs to pickup an object and swipe over the screen against another object.
Now what i’m trying to do is to calculate the speed they are swiping in kilometers an hour.
What i did is give the object they need to hit a collider and created an second sphere collider around it which is larger, when the player enters the second collider a timer goes while (true) { number += Time.deltaTime; yield return new WaitForSeconds(0); }
and i collect the number with the first collider when they enter it.
But the time is always 0.2 when swiping (unless your swiping really slow).
Is there a better way to calculate speed of which they are swiping? it’s probarly a whole different setup but i don’t know how.
Sounds like your accuracy is going to be limited by how far apart your “timing” and “crashing” colliders are. If your player is swiping fast enough, it might only take a single frame to cross the distance between the two.
What you’re looking for is known as estimating instantaneous veolcity, which gets into some math and physics! I’m going to try and solve this with concepts presented in this video.
The first thing we’ll need to do is start storing position history in our object that is moving. We don’t want a history of everywhere it’s ever been because that would start to build up a lot of useless info. Each time we record a new point, we’ll knock out the oldest one – and we only really need just the past 3 points total make the estimation. So we can model our collection of position history as a Queue.
On update, we’ll need to record both the time and position so we can divide to get velocity. I made a little class for this, but you could use a Tuple too.
Then all we have to do is use the equation that is presented in the video (y1 - y0)/(x1 - x0) to make the calculation. Here’s some sample code:
private readonly Queue<MovementInfo> _positionHistory = new Queue<MovementInfo>();
void Update()
{
var time = Time.timeSinceLevelLoad;
var position = transform.position;
_positionHistory.Enqueue(new MovementInfo(time, position));
if (_positionHistory.Count > 3)
{
_positionHistory.Dequeue();
}
}
public float GetVelocity()
{
var positionHistory = _positionHistory.ToArray();
var totalTime = positionHistory[2].time - positionHistory[0].time;
var totalDistance = positionHistory[2].position - positionHistory[0].position;
var velocity = totalDistance.magnitude / totalTime;
return velocity;
}
private class MovementInfo
{
public MovementInfo(float time, Vector3 position)
{
this.time = time;
this.position = position;
}
public float time { get; set; }
public Vector3 position { get; set; }
}
NOTES
Some of this code right now is inherently unsafe. For example, what happens if you call GetVelocity() immediately? positionHistory[2] doesn’t exist and you’ll get an exception. I’ll leave it to you to make sure your specific use case works!