0
\$\begingroup\$

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);
    }
}
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

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);
\$\endgroup\$
1
  • \$\begingroup\$ It worked both ways you suggested. I prefer the one above. Thanks. \$\endgroup\$
    – gunza
    Jan 23, 2022 at 20:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .