# Enemy shake/vibrate when following character

I am using the arongranberg A* path finding project to create way points for one enemy to follow the player. However, the enemy vibrates back and forward by about 0.1 - 0.2 unit distance when moving. I have done a lot of research regarding this problem in the past few days but to no avail I could not find a solution that solves it. This is link to a gif to show what I mean.

I have tried,

changing Application.targetFrameRate = 30;

changing fixed update to update and vice versa;

using rigidbody2d and turn interpolate on plus using velocity to move;

turning iskinematic on and off;

using translate to move.

none of the above solution works. Below is the script I have for my enemy. Any advice would be appreciated.

    using UnityEngine;
using System.Collections;
//Note this line, if it is left out, the script won't know that the class 'Path' exists and it will throw compiler errors
//This line should always be present at the top of scripts which use pathfinding
using Pathfinding;

public class AstarAI : MonoBehaviour
{
//The point to move to
public Transform target;

private Seeker seeker;

//The calculated path
public Path path;

//The AI's speed per second
public float speed = 200;

//The max distance from the AI to a waypoint for it to continue to the next waypoint
public float nextWaypointDistance = 0.02f;

//The waypoint we are currently moving towards
private int currentWaypoint = 0;

Rigidbody2D rb;

public void Start ()
{
rb = this.GetComponent<Rigidbody2D> ();
seeker = GetComponent<Seeker>();

//Start a new path to the targetPosition, return the result to the OnPathComplete function
seeker.StartPath( transform.position, target.position, OnPathComplete );
}

public void GoToNewTarget(Transform newTarget) {
//path = null;
currentWaypoint = 0;
nextWaypointDistance = 0.02f;
target = newTarget;
seeker = GetComponent<Seeker>();
seeker.StartPath( transform.position, target.position, OnPathComplete );
}

public void OnPathComplete ( Path p )
{
Debug.Log( "Yay, we got a path back. Did it have an error? " + p.error );
if (!p.error)
{
path = p;
//Reset the waypoint counter
currentWaypoint = 0;
}
}

public void Update ()
{
if (path == null)
{
//We have no path to move after yet
return;
}

if (currentWaypoint >= path.vectorPath.Count)
{
Debug.Log( "End Of Path Reached" );
return;
}

//this.GetComponent<Rigidbody2D> ().MovePosition (path.vectorPath[currentWaypoint]);
//Debug.Log (path.vectorPath[currentWaypoint]);
//Direction to the next waypoint
Vector3 dir = ( path.vectorPath[ currentWaypoint ] - transform.position ).normalized;
//GetComponent<Rigidbody2D> ().velocity = new Vector2 (dir.x * 3, dir.y * 3);
//Vector3.MoveTowards(transform.position, path.vectorPath[ currentWaypoint ], 2*Time.fixedDeltaTime);
dir *= speed* Time.deltaTime;
rb.velocity = dir;
//this.gameObject.transform.Translate( dir );

//Check if we are close enough to the next waypoint
//If we are, proceed to follow the next waypoint
if (Vector3.Distance (transform.position, path.vectorPath [currentWaypoint]) < nextWaypointDistance) {
currentWaypoint++;
return;
}
}
}

• I think the glitch is in your currentWaypoint. My suggestion is to keep previous dir in everyframe, and where you find normalized direction change, make currentWaypoint =0 or no change in currentWaypoint instead of currentWaypoint++ – Hamza Hasan Feb 25 '16 at 20:36
• We previously solves a similar issue by using a look-ahead (skipping the first waypoint since it should be close) and using obstacle avoidance to avoid walls/round corners. Unfamiliar with unity so I'm not sure how it would appply to your situation – Niels Feb 26 '16 at 12:21

What is most likely happening is you are calling GoToNewTarget before the enemy has finished the path it is currently on (which seems to be the case from the gif).
This is an issue because the path finding library takes some time to find a new path, and in that time the enemy has traveled further down the existing path. When the new path is found, it will start at a point behind the enemy's position (where the enemy was when seeker.StartPath was called), and so the enemy will move backwards to the start of the new path.
To fix this, you can move the next waypoint check to before the movement, and put it in a while loop to make sure you are up to the right waypoint whenever you go to move.