IEnumerator check for return

Hi,
I have a small problem with my code. Function 1 on script 1 is supposed to start function 2 on script two.

IEnumerator moveUnit()
    {
        if (Map.validMovementGameObjects.Contains(this))
        {
            //Generate Pathfinding for Selected Unit to this Tile
            Map.GeneratePathTo(TileX, TileZ);

            // reset all tiles previously shown as selected
            battleSystems.resetAllTilesSelection();

            //Make Unit move to the next Tile
            selectedUnit.StartCoroutine("MoveNextTile");
            yield return selectedUnit.MoveNextTile();

            Debug.Log("is animation still running?");

            //TargetTile is now occupied by the selected unit
            currentlyOccupiedby = selectedUnit;

            //get current selected Tile, reset last
            battleSystems.OccupiedTiles();

            if (selectedUnit.movementPointsLeft >= 1)
            {
                Map.GenerateValidMovementTiles();
            }
            else
            {
                Map.GenerateValidAttackableTiles();
            }
        }
        else
        {
            resetSelection();
        }
        yield break;
    }

Then wait until the function has finished and then resume.
Code 2 / function, that has to finish:

 public IEnumerator MoveNextTile()
     {
        while (movementPointsLeft > 0)
        {
            if (CurrentPath == null)
            {
                yield break;
            }
           
            // Get cost from current tile to next tile
            movementPointsLeft -= Map.CostToEnterTile(CurrentPath[0].x, CurrentPath[0].z, CurrentPath[1].x, CurrentPath[1].z);

            // Move us to the next tile in the sequence
            setTileX = CurrentPath[1].x;
            setTileZ = CurrentPath[1].z;           

            Maptile _targetTile = battleSystems.GetMaptile(getTileX, getTileZ);

            StartCoroutine("TurnShip", _targetTile);
            yield return TurnShip(_targetTile);
            //Debug.Log("here the CurrentPath went missing " + CurrentPath.Count);

            while (Vector3.Distance(transform.position, _targetTile.transform.position) > 0.5f)
            {
                // Debug.Log("Distance " + Vector3.Distance(transform.position, _targetTile.transform.position));               
                transform.position = Vector3.Lerp(transform.position, _targetTile.transform.position, lerpSmoothing * Time.deltaTime);
                yield return null;
            }         

            transform.position = _targetTile.transform.position;   // Update our unity world position

            //Debug.Log("here the CurrentPath went missing " + CurrentPath.Count);
            // Remove the old "current" tile
            CurrentPath.RemoveAt(0);

            if (CurrentPath.Count == 1)
            {
                // We only have one tile left in the path, and that tile MUST be our ultimate
                // destination -- and we are standing on it!
                // So let's just clear our pathfinding info.
                CurrentPath = null;
            }
            yield return null;
        }
     }

my problem is, that when I use:

yield return selectedUnit.MoveNextTile();

to wait for the other function to finish some of the values in code 2 change drasticly.
For example the list:
CurrentPath is suddenly nonexistent.
Alse the value for movementPointsLeft -= Map.CostToEnterTile(CurrentPath[0].x, CurrentPath[0].z, CurrentPath[1].x, CurrentPath[1].z); is suddenly way of.
Thank you for your help.

I’ll start by saying this right here:

selectedUnit.StartCoroutine("MoveNextTile");
yield return selectedUnit.MoveNextTile();

You’re running ‘MoeNextTile’ twice.

Do one or the other yielding either or.

yield return selectedUnit.StartCoroutine("MoveNextTile");
yield return selectedUnit.MoveNextTile();

Or even:

yield return selectedUnit.StartCoroutine(selectedUnit.MoveNextTile());

Note the difference between the StartCoroutine and the yielding the method called is WHO the coroutine runs on. The first it runs on ‘selectedUnit’, and the second it runs on ‘this’. (note the 3rd runs like the 1st)

The implication of this is how it behaves if this or selectedUnit is destroyed/disabled/etc.

I haven’t looked into your other issues personally mainly because this big problem could play a large role in causing you issues (you’re doubling work).

But to guess. CurrentPath may be getting set null because it ran twice which removed more than one entry and you have code that sets it null when the length reaches 1.

Same goes for its values being way off… you’re technically reading further ahead.

3 Likes

thank you ver much this solved my problem. I used this combination one before and assumed that it work, which it only did, because both functions were not contridictary there.