Unity3D Continuous movement using Lerp
There are a lot of posts and videos about moving objects using the lerp method in Unity, but few of them point to the main problem.
before starting please read this post to understand the Lerp method: https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/
as you read in the above post, the lerp method following a simple concept. set the start and end position and the percentage of progress. to calculate the percentage of progress, you need to divide the traveled path by the total path. you can calculate the traveled path with speed:
dx = v * dt
If you have jittery movement, so you are using the lerp method wrong. you must not change the start or end position while moving the object, the points must be static during moving.
Consider a multiplayer game, the server sends the world snapshot (which includes all player’s positions) frequently, so your client must move the other players to certain positions which arrived from the server.
To move an object continuously using lerp, you must lerp the object in a period that has a static start and end position and when arrived in the end position, set a new target position.
while using this method, you maybe got a lag while changing the target position. look at the slope of the position-time diagram:
So what is the problem? the problem is the frame rendering time (Time.deltaTime) which is out of sync with lerp time.
Take a look at this script from (https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/):
The script is adding Time.deltaTime (frame rendering time) value to currentLerpTime in line 22, then check if the currentLerpTime is greater than lerpTime, set the value of lerpTime to currentLerpTime, so the maximum value of perc could be 1 (means that the object has arrived in the end position).
The problem for continuous lerping is here exactly, when currentLerpTime is greater than lerpTime that means rendering took more time than the total lerpTime, so the object must be a little forwarder than end position and the object is in the next target lerping progress.
To fix this, we need to calculate the subtraction of currentLerpTime and the lerpTime when it’s greater than lerpTime. the result is the currentLerpTime of the next target lerping progress. then set the value of endPos to startPos (next target start position), set the new target position to the endPos (new target), and use the subtraction of currentLerpTime and lerpTime as the currentLerpTime.
This script tries to move the object to a new random position (between 100 to 120 unit forwarder) after arriving in the endPos.
Also if the currentLerpTime (sum of Time.deltaTime — frame rendering time) is greater than lerpTime (total of lerp time), pick a new target and set the subtraction of them to currentLerpTime.
Check this diagram:
This diagram shows the lerp result of moving an object from position 0 to 5 in 40ms, because of linear movement, the speed in this period is 0.125m in each ms. you can see the result of the lerp method in each frame. the problem exists in frame number 4. currentLerpTime is 44ms (greater than total lerp time that is equal to 40ms) so the percentage of progress is 1.1 which is greater than 1. as you know, the third parameter of the Lerp method (percentage of progress) must be between 0 and 1, so the lerp method returns the end position that is 5, but the object must travel 0.1 percentage of the next target progress and right position is 5.5 (consider speed is constant). if you set the new target here without applying the 0.1 extra percentage, the object jitters in each end position. as I said before to prevent this, we must pick a new target (even with a new speed) and calculate new percentage of it to move the object in the exact right position.