Hey guys, I need some help :slight smile:
I want to move a sprite along a path. That path is over 256px. It starts from A:(X:160, Y:576) to B:(X:416, Y:576). How can I get the duration that I need to travel von a to b? My first try was to calculate the distance between the to vectors and than divide that result by the speed in pixels.
var movementSpeed = 32 * 5;
var length = Vector2.Distance(startPosition, targetPosition);
var duration = (length / movementSpeed); // 1.6 seconds
After that, I use Vector2.Lerp to move. It traveled within 1.6 seconds to its target.
But If I use the way to move it by gametime I would wrote something like:
var direction = Vector2.Normalize(targetPosition - startPosition);
var vel = direction * movementSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
I move the same way in 1.4 seconds. Both times I set fixed timestamp + vsync (60 fps).
Where is my mistake?
maybe floating point precision and quantization of gametime (fixedtimestep). I guess it’s not exactly 1.6 or 1.3 seconds, is it?
not sure how you define the “reached the end” of the second approach, but as you calc the direction new every time, the precision will lower when you come nearer to the target (it will most likely never reach exactly zero) - that can be another reason - depending on how you determine when “the target is reached”. Your first approach is actually deterministic, while the second isn’t
Maybe you snap position to integer coordinates at some point? By clamping or rounding a float value to int, or somehow snapping to pixel coordinates? You would lose subpixel precision, making jumps slightly longer or faster, relatively randomly.
Under fixed timestep if the frames per second are invariant.
length / by speed = depends on the number of steps per second to traverse a distance not time to traverse a distance. Fixed time step is not even invariant unfortunately in the steps it takes to complete a second.
If i am running at 10000 frames per second vs 60 frames per second i will not traverse the distance a to b at the given speed equally under different timesteps because the speed implys their would be the same number of steps in a second. So unless my speed is affected by target elapsed time i will not get the right result.
If the speed is invariant over time but variable per frame which is preferable currently as mgs fixed timing is a bit screwed up.
Then you change the calculation to be dependent on velocity over time not distance per step.
// which means your speed is affected by target elapsed time each frame.
var i = 1f / elapsedTimeThisFrame; // iterations per second (you will find under fixed this is about 58.86);
var d = Vector2.Distance(a,b); // distance
var timeToTraverse = d / myObjects.SpeedPerSecond;
var framesRequired = timeToTraverse * i;
// this is then the speed you should add this frame to your object.
var speedOfMyGameObjectThisFrame = myObjects.SpeedPerSecond * elapsedTimeThisFrame;
The above here is approximated because it is dependent on having a accurate timing device per frame then a accurate number of frames per second which as stated earlier mg does not.
However this is a much closer approximation this way then the first.
Either way is not really perfect though if there is a lag spike you would skip forward in this scenario.
You can also see that if you accelerated in either situation your time to traverse would change.
To summerize the assumption that there is 60 fps in a fixed time step set to 60 fps is (Wrong).
Test it and see for yourself.
Thank you guys,
the post from @willmotil does explains the issue I have. The other issue was, that I used Vector.Lerp. In Unity3d there is a MoveTowards method (https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Vector2.cs) the code here helps me a lot. Now its working as I expected, even under different framerate.
I was just typing up a lengthy reply about apparent errors in your calculations, but I just discarded it 'cause I see the problem was resolved. XD It took me a few minutes to work out how it came out correctly in spite of them. Turns out it was a matter of terminology. You lot are using the word “speed” to describe “displacement” - that is, how far something moves in a given interval. Speed is distance/time, and doesn’t depend on time steps, whereas displacement is (amongst other things) distance/time * frame duration, which clearly does depend on the time increments. “Speed per second” is either redundant or would refer to acceleration.
You might say that I’m splitting hairs about semantics, but this did lead to a lot of confusion on my part as I was trying to make sense if this, and could for others as well.