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!