Coroutine рекурсия не понимаю поведение

У меня Coroutine начинает работать независимо от:

yield return new waitforseconds(filltime)

Всё сразу выполняется:

    private IEnumerator FindAndDestroyNearestPieces(int column, int row, MatchedType type)
        {
            int distance = 1;
            List<Vector2Int> pos = new List<Vector2Int>();
            if (_boardSetup.AllPieces[column,row]!=null)
            {
                _boardSetup.AllPieces[column,row].ClearableComponent.ClearPiece();
            }
            
            for (int i = -distance; i <= distance; i++)
            {
                for (int j = -distance; j <= distance; j++)
                {
                    int targetRow = row + i;
                    int targetColumn = column + j;
                    if (IsValidPosition(targetColumn, targetRow) &&
                        _boardSetup.AllPieces[targetColumn, targetRow].GamePieceData.MatchedType == type &&
                        _boardSetup.AllPieces[targetColumn, targetRow] != null)
                    {
                        pos.Add(new Vector2Int(targetColumn,targetRow));
                        _boardSetup.AllPieces[targetColumn,targetRow].ClearableComponent.ClearPiece();
                    }
                }
            }
            if (pos.Count>0)
            {
                foreach (var piecePos in pos)
                {
                    yield return new WaitForSeconds(fillTime);
                    yield return StartCoroutine(FindAndDestroyNearestPieces(piecePos.x, piecePos.y,MatchedType.Normal));
                }
                pos.Clear();
            }
        }

Ответы (1 шт):

Автор решения: aepot

yield return StartCoroutine здесь не надо yield return.

А вообще, у вас корутина неконтролируемое количество раз сама себя запускает, так как проверка наличия элементов в списке и его очистка происходят во время выполнения вообще в разных корутинах. Путаница в логике, разбейте метод на 2 части. Один пусть выполняет логику, второй пусть будет корутиной, которая запускает логику, не надо рекурсий.

Я если честно, сам до конца не понимаю, что происходит в коде, но решение может выглядеть примерно так.

private DestroyNearestPieces(int column, int row, MatchedType type, List<Vector2Int> pos)
{
    const int distance = 1;
    if (_boardSetup.AllPieces[column,row] != null)
    {
        _boardSetup.AllPieces[column,row].ClearableComponent.ClearPiece();
    }
            
    for (int i = -distance; i <= distance; i++)
    {
        for (int j = -distance; j <= distance; j++)
        {
            int targetRow = row + i;
            int targetColumn = column + j;
            if (IsValidPosition(targetColumn, targetRow) &&
                _boardSetup.AllPieces[targetColumn, targetRow].GamePieceData.MatchedType == type &&
                _boardSetup.AllPieces[targetColumn, targetRow] != null)
            {
                pos.Add(new Vector2Int(targetColumn,targetRow));
                _boardSetup.AllPieces[targetColumn,targetRow].ClearableComponent.ClearPiece();
            }
        }
    }
}

private IEnumerator FindAndDestroyNearestPieces(int column, int row, MatchedType type)
{
    List<Vector2Int> pos = new List<Vector2Int>();
    DestroyNearestPieces(column, row, type, pos);
    while (pos.Count > 0)
    {
        Vector2Int[] pieces = pos.ToArray();
        pos.Clear();
        foreach (var piecePos in pieces)
        {
            yield return new WaitForSeconds(fillTime);
            DestroyNearestPieces(piecePos.x, piecePos.y, MatchedType.Normal, pos);
        }
    }
}
→ Ссылка