Infinite for loop and List problem

I’m currently working on a game where the player can draw a line on the screen, on the player character will move to and along the line, removing points from the line after the character reaches them.

I’m currently trying to implement the removal part of the code, but I’m running into a problem where Unity will crash due to what I expect to be an infinite for loop. Here is the code I’ve got so far, and the for loop I believe is causing the problem is on line 49 of MoveOnLine.cs. Strangely however, the first time it runs through the for statement, there is no crash. Rather it only happens when the character tries to run the code at the next point that it crashes.
MoveOnLine.cs

public class MoveOnLine : MonoBehaviour
{
    public GameObject gameController; // Object that holds the DrawLine script
    DrawLine lineInfo; // variable to use/assign to DrawLines' values

    List<Vector2> newPositions = new List<Vector2>(); // List used to increment the line's values
    public float speed; // Player speed
    Rigidbody2D rb; // Player's Rigidbody

    private void Start()
    {
        lineInfo = gameController.GetComponent<DrawLine>();
        rb = GetComponent<Rigidbody2D>();
    }

    private void FixedUpdate()
    {
        Vector2 currentPos = new Vector2(transform.position.x, transform.position.y);

        // if a line exists...
        if(lineInfo.currentLine != null)
        {
            // Move the character towards the first point of that line
            transform.position = Vector3.MoveTowards(currentPos, lineInfo.fingerPositions[0], 
                Time.fixedDeltaTime * speed);

            // When the character position is the same as the first point's position...                         
            // ...this block of code *should* move all the values over by one...
            // ...so that fingerPositions[0] becomes fingerPositions[1], etc.
            if (currentPos == lineInfo.fingerPositions[0])
            {              
                int newPositionCount = lineInfo.fingerPositions.Count - 1;
                Debug.Log(newPositionCount);

                // Goes through each spot on the fingerPositions list + 1, to get the "new" finger positions
                for (int i = 0; i < newPositionCount; i++)
                {
                    newPositions.Insert(i, lineInfo.fingerPositions[i + 1]);
                }

                // Changes the original line's positions to the new positions, essentially removing...                                                                     
                // ...point 0 of fingerPositions
                lineInfo.fingerPositions = newPositions;

                // Repeats the process if it's the first point of a line, because each line starts...                                                 
                // ...with two points (in case it's a dot)
                if (lineInfo.firstPoint)
                {
                    for (int i = 0; i < newPositionCount; i++)
                    {
                        newPositions.Insert(i, lineInfo.fingerPositions[i + 1]);
                    }

                    lineInfo.fingerPositions = newPositions;
                }
            }
        } 
    }
}

DrawLine.cs (this is in charge of drawing the line of the screen, so I’m including it for the context of variables)
public class DrawLine : MonoBehaviour
{
public GameObject linePrefab; // Line Object to Instantiate
public GameObject currentLine; // Object that holds the currently Instantiated line
public bool firstPoint; // Does this line still have it’s first points to account for a dot?

public LineRenderer lineRenderer;
public EdgeCollider2D edgeCollider;
public List<Vector2> fingerPositions; // List to hold finger/mouse points for the line

// Update is called once per frame
void Update()
{
    // Input Starts the line
    if (Input.GetMouseButtonDown(0))
    {
        Destroy(currentLine); // if there is already a line on the screen, destroy it
        CreateLine();
    }
    // Input Continues drawing the Line
    if (Input.GetMouseButton(0))
    {
        Vector2 tempFingerPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        if (Vector2.Distance(tempFingerPos, fingerPositions[fingerPositions.Count - 1]) > 2f) // if previous point is further than X...
        {
            UpdateLine(tempFingerPos); // ... add the new finger position to the list via the method
        }
    }

    // Allows the player to delete the current line on the screen
    if (currentLine != null && Input.GetKeyDown(KeyCode.Delete))
    {
        Debug.Log("Destroying Line");
        Destroy(currentLine);
    }

    // Used to see if the line still has it's first two point to account for a dot of not
    if (currentLine != null && fingerPositions[0] == fingerPositions[1])
    {
        firstPoint = true;
    } else if (currentLine != null && fingerPositions[0] != fingerPositions[1])
    {
        firstPoint = false;
    }
}

// Method to start drawing the line
void CreateLine()
{
    currentLine = Instantiate(linePrefab, Vector3.zero, Quaternion.identity); // Creates the line Prefab
    lineRenderer = currentLine.GetComponent<LineRenderer>(); // Gets the Components from the Prefab
    edgeCollider = currentLine.GetComponent<EdgeCollider2D>();
    fingerPositions.Clear(); // Clear the list of points from the previous line

    // Immediately adds two points so that a line so even if the line is a dot...                                               
    // ...it will start being drawn
    fingerPositions.Add(Camera.main.ScreenToWorldPoint(Input.mousePosition));
    fingerPositions.Add(Camera.main.ScreenToWorldPoint(Input.mousePosition));
    lineRenderer.SetPosition(0, fingerPositions[0]);
    lineRenderer.SetPosition(1, fingerPositions[1]);
    edgeCollider.points = fingerPositions.ToArray(); // Adds the Vector2 points to the list
}

// Method to continue drawing the line
void UpdateLine(Vector2 newFingerPos)
{
    fingerPositions.Add(newFingerPos); // Adds a new point at the finger/mouse Pos
    lineRenderer.positionCount++; // Adds a new position for the line
    lineRenderer.SetPosition(lineRenderer.positionCount - 1, newFingerPos); // sets the position to the new Vector2 (the -1 is because the count starts at 0)
    edgeCollider.points = fingerPositions.ToArray(); // Adds the Vector2 point to the list
}

Any help is greatly appreciated! I’m also still new to Unity Answers so if my formatting is off or that I should be adding any (or removing any useless) info please also let me know!

It’s very hard to tell what went wrong here… Your solution is little bit overcomplicated. Did you get any exception?

If u want move your character along a straight line, the only thing you need is:


  1. Vector2 StartPoint;
  2. Vector2 EndPoint;

You can get these values from Input.GetMouseButtonDown and Input.GetMouseButtonUp


After that you can move your character by using Vector2.Lerp(StartPoint, EndPoint, t) in FixedUpdate function.

Ok, it turns out I was using code I didn’t fully understand (and as blaskojoz pointed out, overly complicated). List.Insert() upon reading up more on is definitely not what I thought it meant, and I ended up replacing it with List.RemoveAt() instead, which both removes the infinite loop and achieves what I was hoping. Thanks everyone for the help!