# How to move a character gradually over a list of waypoints?

I have a list whose elements are Vector2 points in world space:

1. (9, -9)

2. (9, -13)

3. (5, -13)

What I want is that my enemy character should first go to (9, -9) position, after reaching that target, go to (9, -13) position, and after reaching there, move to (5, -13).

I tried this in the script below. I gave the first element of the list to MoveTowards as a target, but before my character could reach its target, the next element of the list was given as a target.

How can I do this without using the for-loop? Or how can I temporarily stop the for-loop until my character reaches its destination?

public Rigidbody2D rb;

private float speed = 2f;

public Vector2 target;

public NewNavmesh pathTarget;

private void Update()
{
for (int i = 0; i < pathTarget.ways.Count; i++)
{
target = pathTarget.ways[i]; //Vector2 paths in new list
transform.position = Vector2.MoveTowards(this.transform.position, target, speed * Time.deltaTime);
int indexInList = pathTarget.ways.IndexOf(pathTarget.ways[i]);
pathTarget.ways.RemoveAt(indexInList);
}
}


It looks like you meant to write something like this:

void Update() {

// When the ways list is empty, we've reached the last waypoint.
if (pathTarget.ways.Count > 0) {

// Move one step toward the next remaining point in the list.
target = pathTarget.ways[0];
transform.position = Vector2.MoveTowards(
transform.position,
target,
speed * Time.deltaTime
);

// If we've reached the waypoint, remove it from the list,
// so that next frame we proceed to the next waypoint after it.
if ((transform.position - target).sqrMagnitude < 0.001)
pathTarget.ways.RemoveAt(0);
}
}


Or, if you like conceiving of this as a for loop, you could do it non-destructively this way:

IEnumerator WalkWaypoints(List<Vector2> waypoints) {
foreach (var waypoint in waypoints) {
while ((transform.position - waypoint).sqrMagnitude > 0.001f) {
transform.position = Vector2.MoveTowards(
transform.position,
target,
speed * Time.deltaTime
);
// Wait a frame,
// and resume the next loop iteration next frame.
yield return null;
}
}
}


You can then set this in motion with:

Coroutine walk = StartCoroutine(WalkWaypoints(pathTarget.ways));


And abort it with:

StopCoroutine(walk);

• It worked both ways you suggested. I prefer the one above. Thanks. Commented Jan 23, 2022 at 20:34