How to avoid the 2D movement flickering with MoveTowards or Lerp?

Hello,

I’m simply trying to move bodies around smoothly in a constant speed, but I’m getting flickering; looks like it keeps freezing/slowing down while moving.

I’m using the A* Pathfinding Project and navigating each waypoint, so I can’t just use Lerp/Translate the direction of a key pressed and stop moving when the key is up for instance. I need to go through each waypoint (which I managed).

But the problem is: even if I just put manually to go from point A to point B I still get the flickering, even in straight lines.

So far I tried 3 approaches:

  • MoveTowards: this is the one that is working the better so far, but still flickers.
  • Lerp: the body “freezes” in position a LOT.
  • Translate: looks like the smoother one, but then I didn’t manage to detect when it reaches a waypoint. Sometimes it detects proximity with a waypoint and sometimes it doesnt. So most of the times it keeps moving indefinetely in a direction.

Final question is: How to move without flickering with a constant speed?

CODE/PLAYER:
Web Player to test each approach (middle click anywhere to place a destination point and the target will move; and the top buttons can change the movement approach): https://dl.dropboxusercontent.com/u/11453596/Unity/MovementTypes/MovementTypes.html

Code for each approach:
MOVE TOWARDS:

          if(canMove)
          {
               Vector3 currentPosition = t.position;
               List<Vector3> vPath = path.vectorPath;

               if(path != null  (currentWaypoint == -1 || currentPosition == activeTarget))
               {
                    int prevWaypointIdx = currentWaypoint;

                    currentWaypoint++;
                    if(currentWaypoint == 0) currentWaypoint = 1;
                         
                    if (currentWaypoint < path.vectorPath.Count)
                    {
                         activeDirection = path.vectorPath[currentWaypoint] - t.position;
                         activeDirection.z = 0;
                         activeDirection.Normalize();

                         activeTarget = path.vectorPath[currentWaypoint];
                    }
                    else
                    {
                         canMove = false;
                    }
               }

               if(canMove)
               {
                    t.position = Vector3.MoveTowards(currentPosition, activeTarget, speed * Time.deltaTime);
               }
          }
     }

LERP:

	protected float XZSqrMagnitude (Vector3 a, Vector3 b) {
		float dx = b.x-a.x;
		float dy = b.y-a.y;
		return dx*dx + dy*dy;
	}

          if(canMove)
          {
               Vector3 currentPosition = t.position;
               List<Vector3> vPath = path.vectorPath;

               if(path != null  (moveTime == 0f || moveTime >= 1f))
               {
                    int prevWaypointIdx = currentWaypoint;

                    currentWaypoint++;
                    if(currentWaypoint == 0) currentWaypoint = 1;
                         
                    if (currentWaypoint < path.vectorPath.Count)
                    {
                         activeDirection = path.vectorPath[currentWaypoint] - t.position;
                         activeDirection.z = 0;
                         activeDirection.Normalize();

                         activeTarget = path.vectorPath[currentWaypoint];
                    }
                    else
                    {
                         canMove = false;
                    }

                    moveTime = 0f;
               }


               if(canMove)
               {
                    if(moveTime <= 1f)
                    {
                         moveTime += Time.deltaTime * (speed/gridSize) * 0.7071f;
                         t.position = Vector3.Lerp(currentPosition, activeTarget, moveTime);
                    }

                    if(XZSqrMagnitude(t.position, finalTarget) < 0.0000001f)
                    {
                         Debug.Log (XZSqrMagnitude(t.position, finalTarget));
                         Debug.Log (" Move Completed ");
                         canMove = false;
                    }
               }
          }

TRANSLATE:

          if(canMove)
          {
               Vector3 currentPosition = t.position;
               List<Vector3> vPath = path.vectorPath;
               bool moveNext = false;

               // Sometimes it correctly detects proximity, but most of the time this is ignored
               if(XZSqrMagnitude(t.position, activeTarget) < 0.0001f)
                    moveNext = true;

               if(path != null  (moveNext || currentWaypoint == -1 || currentPosition == activeTarget))
               {
                    int prevWaypointIdx = currentWaypoint;

                    currentWaypoint++;
                    if(currentWaypoint == 0) currentWaypoint = 1;
                         
                    if (currentWaypoint < path.vectorPath.Count)
                    {
                         activeDirection = path.vectorPath[currentWaypoint] - t.position;
                         activeDirection.z = 0;
                         activeDirection.Normalize();

                         activeTarget = path.vectorPath[currentWaypoint];
                    }
                    else
                    {
                         canMove = false;
                    }
               }


               if(canMove)
               {
                    t.Translate(activeDirection * speed * Time.deltaTime, Space.World);
               }
          }

Since it’s been on the 3rd page already, bump. So far I am going with the MoveTowards option, but still AI buddies are moving freezing/flickering, which is rather annoying.

note sure what platform/browser you are on. But windows 7 + firefox/chrome translate/moveTowards are smooth i.e. no flickering.Lerp is abit jerky