简体   繁体   中英

Unity C# Yield WaitForSeconds within For Loop Only Works Once

I am trying to use two yields within a coroutine loop (because I need to iterate out arrays with pauses between each loop).

The first loop works correctly, with all the yields working for the right amount of time. By the second loop, the yield return new WaitForSeconds() begins counting down right away, not waiting for the yield and code before it to complete (it seems). By the time of the third loop, the timing is all off.

I tried using a while loop instead of a for but got the same result.

TLDR: I need to loop out my arrays with pauses between each one. How can I use more than one yield past the first loop through in a coroutine?

public IEnumerator doPathfinding()
{
    for (int i = 0; i < waypoint.Length; i++)
    {

        // get first waypoint from array
        var _waypoint = waypoint[i];

        // get node on A* of cloest waypoint
        closestPointOnNavmesh = AstarPath.active.GetNearest(_waypoint.transform.position, NNConstraint.Default).clampedPosition;

        // Move towards destination
        ai.destination = closestPointOnNavmesh;

        // Wait until within X range of waypoint
        yield return new WaitUntil(() => distanceReached == true);

        // Agent is now at waypoint and automatically stops. Wait 5 seconds before looping to next waypoint.
        yield return new WaitForSeconds(5f);

    }

    Debug.Log("Loop End");
}


    public override void OnUpdate()
    {

        // Get current distance to the target. If distance is less than offset, then sent event.    
        currentDistance = Vector3.Distance(go.transform.position, closestPointOnNavmesh);
        if(currentDistance <= arrivalOffset.Value)
        {
            distanceReached = true;
        }
        else
        {
            distanceReached = false;
        }


    }

The code inside the couroutine is fine, it works as intended.

Most probably, based on the issue you reported, you're calling more than once the coroutine at the same time.

Use a bool to check if the coroutine has already started or not, like this:

bool isDoPathFindingRunning = false;
IEnumerator = doPathFinding();

private void Awake() {
    pathFinding = doPathfinding();
}

private void WhereeverYouStartCoroutine() {
    if (!isDoPathFindingRunning)
        StartCoroutine(pathFinding);
}

public IEnumerator doPathfinding() {
    isDoPathFindingRunning = true;
    // Do your stuff
    isDoPathFindingRunning = false;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM