Unity Freeze and Takes up more and more Memory until I End Task

Hello, I am working on a 2d game and for some reason when I press play it freezes. It takes up more and more memory until I go into task manager, and shut it down. All this started when I tried to make my own world generation script. I fully realize this might be because of an endless loop, but I looked through my code and could not find one. Any help would be appreciated.

Generation Code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WorldGeneration : MonoBehaviour
{

    public GameObject[] forestGeneration;
    public int genType;
    public float chance;
    public List<Transform> generationSpots;
    public List<Transform> previousGenerationSpots;

    public float minX;
    public float maxX;
    public float minY;
    public float maxY;

    public float minSpaceApart;

    public GenType generationType;
    public Vector2 genOffset;

    public bool firstGen;
    public bool secondGen;
    public bool done;
    public List<bool> theDistance;
    List<bool> blank;

    public GameObject worldObject;

    private void Start()
    {

        firstGen = true;
        genType = generationType.generationType;

        if(genType == 1)
        {

            float boolnum;
            minSpaceApart = 3;
            chance = 0.01f;
            forestGeneration = generationType.genForest;

            for (int i = 0; i < 1000 * chance; i++)
            {

                boolnum = 0;
                GameObject spawnSpot = Instantiate(worldObject, new Vector2(Random.Range(minX, maxX), Random.Range(minY, maxY)), Quaternion.identity);
                generationSpots.Add(spawnSpot.transform);
                Vector2 position = new Vector2(spawnSpot.transform.position.x, spawnSpot.transform.position.y);

                if(previousGenerationSpots.Count > 0 && !firstGen)
                {

                    done = false;

                    for (int c = 0; c < previousGenerationSpots.Count; c++)
                    {

                        Vector2 pastPosition = previousGenerationSpots[c].position;
                        float distance = Vector2.Distance(position, pastPosition);

                        Debug.Log(distance);

                        if (secondGen)
                        {

                            if(Vector2.Distance(previousGenerationSpots[c].position, position) > minSpaceApart)
                            {

                                theDistance.Add(true);
                                boolnum++;

                            } else {

                                theDistance.Add(false);

                            }

                        } else {

                            if (Vector2.Distance(previousGenerationSpots[c].position, position) > minSpaceApart && !secondGen)
                            {

                                if(theDistance.Count < c + 2)
                                {

                                    theDistance.Add(true);
                                    boolnum++;

                                } else {

                                    theDistance[c] = true;
                                    boolnum++;

                                }

                            } else if (Vector2.Distance(previousGenerationSpots[c].position, position) > minSpaceApart) {

                                if (theDistance.Count < c + 2)
                                {

                                    theDistance.Add(false);

                                }
                                else
                                {

                                    theDistance[c] = false;

                                }

                            }

                        }

                        if (c == previousGenerationSpots.Count - 1)
                        {

                            secondGen = false;
                            done = true;

                            if (done == true && boolnum == theDistance.Count)
                            {

                                done = false;
                                previousGenerationSpots.Add(generationSpots[i]);
                                GameObject spawn = Instantiate(forestGeneration[Random.Range(0, forestGeneration.Length)], generationSpots[1].position, Quaternion.identity);
                                spawn.transform.parent = spawnSpot.transform;

                            }

                        }

                    }

                } else {

                    if (firstGen)
                    {

                        secondGen = true;
                        firstGen = false;
                        previousGenerationSpots.Add(generationSpots[i]);
                        Vector2 offsetPos = new Vector2(generationSpots[i].position.x - 8, generationSpots[i].position.y - 8);
                        GameObject spawn = Instantiate(forestGeneration[Random.Range(0, forestGeneration.Length)], offsetPos, Quaternion.identity);
                        spawn.transform.parent = spawnSpot.transform;

                    }

                }

            }

        }
      

    }

}

Generation Type Code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GenType : MonoBehaviour
{
  
    public int generationType;
    public string Forest = "1";
    public string Plain = "2";

    public GameObject[] genForest;

}

Any Ideas to increase Performance?

First suggestion is to improve code quality. It is difficult to read. Here are some things that could be improved, and refactoring usually helps spot the deeper problems that are wrong.

Areas to improve:

  • formatting - I suspect this is just from copy/pasting into your browser, but please fix the extra spacing. It’s hard to read, and people on the forum like helping when it’s easy to do so.
  • reduce the maximum level of indentation by removing nested if statements. What people consider ‘good’ varies: some consider nested ifs greater than 2-deep to be bad due to decreasing code readability, and 2-deep is only acceptable when what’s between the brackets is small. Often, you can create methods for what’s inside a loop or inside an if {}. For example, instead of this:
if(genType == 1)
{
    // gigantic block of code
}

change it to

if(genType == 1)
{
   GenerateType1();
}
  • don’t call things ‘type 1’ - that’s not meaningfully named. Will you remember what the difference between type1 and type2 6 months from now? If you bring more people onto your project, do you want to have to explain it?

  • break off duplicate code, for example here’s a statement that appears multiple times that could be a method call:

forestGeneration[Random.Range(0, forestGeneration.Length)]
--->
GetRandomForestGen()
  • most importantly, fix whatever is going on with your bools. You have a list of bools which seemingly is for counting how many bools you have (theDistance), and you have bools firstGen, secondGen and done. But you also have a boolnum variable. This is where I decided not to figure out what the actual performance / looping problem was, but to advise refactoring. Keeping track of a bunch of bools makes understanding the code tedious. Perhaps you could increment a single integer, generation, which changes how it behaves? Perhaps you should simply have a few different loops, one for each different generation. That would save you from so many nested ifs and bool state management.

Try refactoring it really well and I’m sure it will become much more apparent where the issue lies.

1 Like

Lo-renzo made some great points. I would also add that, judging from your code style, you’re pretty new to programming. That’s ok–everyone starts somewhere. But writing a whole forest generation algorithm is pretty ambitious for someone so new.

I would recommend commenting out the whole script (no need to delete everything) and starting from scratch. Instead of a whole forest with multiple generation steps, can you spawn a single tree without the editor freezing? Better yet, can you do it with minimal code that’s extremely readable?

Get the absolute simplest form of your algorithm working first. Then add tiny features, one at a time, testing constantly. As soon as something goes wrong, stop and try to fix it. Making the code longer and more complex at that point is only going to make things harder on you.

1 Like

Fixed this a while ago, A loop was never ending. Although after reading these I do agree and have updated my coding strategy, thanks.