Script Crashing Unity

I have a script that I found on Unity Answers that generates a galaxy of cubes. I tried out the script, but it proved too much work and unity crashed. I thought ok, it generates 1000 stars, so i’ll lower all the values. I lowered stars, arms, radius and spread, but it still crashes. Eventually, I lost patience and set it to make 5 stars, 1 arm, 10 radius and 5 spread, but IT STILL CRASHES. I have no idea if it’s my computer, but I have 4GB RAM and i’ve made games that do much more effort than generating 5 cubes, but don’t even lag, let alone crash.

public int numberArms = 6;

public int numberStars = 1000;

public float galaxyRadius = 500f;

public int spread = 100;

float fHatRandom(float fRange)
{
    float fArea = 4 * Mathf.Atan(6.0f);
    float fP = fArea * Random.value;
    return Mathf.Tan(fP / 4) * fRange / 6.0f;
}
 
float fLineRandom(float fRange)
{
    float fArea = fRange * fRange / 2;
    float fP = fArea * Random.value;
    return fRange - Mathf.Sqrt(fRange * fRange - 2 * fP);
}
// Use this for initialization
void Start()
{
    Random.seed = 100;
 
    int starsPerArm = numberStars / numberArms;
    float fAngularSpread = spread / numberArms;
    float fArmAngle = (360 / numberArms);
    for (int arm = 0; arm < numberArms; arm++)
    {
        for (int i = 0; i < starsPerArm; i++)
        {
            float fR = fHatRandom(galaxyRadius);
            float fQ = fLineRandom(fAngularSpread);
            float fK = 1;
 
            //float fA = numberArms * (fArmAngle);
            float fA = arm * fArmAngle;
 
            float fX = fR * Mathf.Cos(Mathf.Deg2Rad * (fA + fR * fK + fQ));
            float fY = fR * Mathf.Sin(Mathf.Deg2Rad * (fA + fR * fK + fQ));
 
            Vector3 starPos = new Vector3(fX, fY, arm * 4);
            Collider[] colliders = Physics.OverlapSphere(starPos, 15);
 
            if (colliders.Length == 0)
            {
                GameObject star = GameObject.CreatePrimitive(PrimitiveType.Cube);
                star.transform.position = starPos;
                star.transform.parent = transform;
                Debug.Log(starPos);
            }
            else
            {
                i--;//because they overlapped, we try again.
            }
        }
    }
}

What you’ve got yourself here is a good old fashioned infinite loop. The main reason is you can’t fit that many objects in your specified space. Consider the following:

	public int numberArms = 6;
	public int numberStars = 1000;
	public float galaxyRadius = 500f;

In the above, with your code loop you are asking for 6 arms to be created, with each arm containing 1000 cubes, or stars in this case. You want the program to therefore create 6000 cube blocks.

				Collider[] colliders = Physics.OverlapSphere(starPos, 15);
				
				if (colliders.Length == 0)
				{
				//Code Here
				}
				else
				{
					i--;//because they overlapped, we try again.
				}

Now considering the above, each time you create a new star, you ask it to grab all colliders within a 15f range, if something is within range it will now generate a new location and move the counter back one, so no stars are lost. This section, along with your galaxyRadius float is where the problem occurs, there’s no possible way all of the blocks will fit in your constraints of space. The program enters an infinite loop and will never stop because it’s never satisfied with the placement of the object.

Consider adding the following:

int ErrorCount; //Add these as declarations
int TotalErrors;
int TotalStars;

TotalErrors = 50000; //Put this at the beginning of your Start

Replace from else onward with the below:

    				else
    				{
    					i--;//because they overlapped, we try again.
    					ErrorCount++;
    					if(ErrorCount > TotalErrors)
    					{
    						Debug.Log ("Program Error, Aborting at star " + TotalStars);
    						i = starsPerArm + 1;
    						arm = numberArms + 1;
    					}
    				}
    			}
    		}
    		Debug.Log ("Finished, there were " + ErrorCount + " recalculations needed and " + TotalStars + " Stars generated.");
    	}
    }

Now when you run the code it will automatically error if it reaches 50K recalculations required, and let you know how far it was able to go. In my case it errors after the 128th star and 50,001 retries.

Now you can start to adjust your values and see how far it goes - for instance, reduce the OverlapSphere value from 15 to 10. This should finish creating the entire galaxy instead of giving and error. From here you should be able to tweak the code to your liking to get everything working exact.

Hope this helps!

Also: if you use Random.seed = 100; this will generate the exact same galaxy each time, I would recommend using Random.seed = (int)System.DateTime.Now.Ticks; - it won’t give much of a variation but there will at least be some.