newb stuck in infinite loop

Hi, I’m very new to programming I barely know C# syntax, I’m trying to get the feel of unity, and work on making stuff daily but right now I’m really stuck in an infinite loop that freezes unity. Right now i want to generate a bunch of meshes at random positions (I cant get at the random position part yet because this doesn’t work yet), here is what i have so far

using UnityEngine;
using System.Collections;

public class GenerateStars : MonoBehaviour {

	// Use this for initialization
	void Start () {
	}
	
	// Update is called once per frame
	void Update () {
        Generate();
	}

    public void Generate()
    {
        for (int i = 0; i < 10; i++)
        {
            Instantiate(this, new Vector3(1, 1, 1), Quaternion.identity);
        }
    }
}

I’ve tried throwing the Generate method in start because that makes more sense, but nothing gets instantiated it just flat out freezes. But if i put the generate in update it starts making a bunch of meshes then freezes quickly. I would think with the if statement the function would stop, but now that i think about it, the update is probably just recalling the generate function over and over regardless of if it stops or not, so how would i make it stop at <10? Thanks

I think that your script instantiates 10 Objects per script. And these objects has its own script that instantiates 10 objects more, and so on. This is not what you want :wink: You should instantiate your objects in Start(), and have your script in another gameobject (Empty if you want or the camera) that instantiates your “star”-objects. I have redesigned your code, take a look:

using UnityEngine;
using System.Collections;

public class GenerateStars : MonoBehaviour {
	
	// drag the prefab into this slot in the inspector view
	// [SerializeField] is for the variable to show up in the inspector view
	[SerializeField]
	private GameObject obj;
	[SerializeField]
	private int NumOfStars = 10;
	[SerializeField]
	private GameObject SpawnBox;
	
	private Vector3 SetBoxBoundaries()
	{
		Vector3 LocalPosition;
	    BoxCollider Boundaries = SpawnBox.GetComponent<BoxCollider>();
	    
		// Get the random local position in SpawnBox
	    float random = Random.value;
		LocalPosition.x = Mathf.Lerp(Boundaries.center.x+SpawnBox.transform.position.x-Boundaries.extents.x*SpawnBox.transform.localScale.x, 
									 Boundaries.center.x+SpawnBox.transform.position.x+Boundaries.extents.x*SpawnBox.transform.localScale.x,
									 random);
		
		random = Random.value;
		LocalPosition.y = Mathf.Lerp(Boundaries.center.y+SpawnBox.transform.position.y-Boundaries.extents.y*SpawnBox.transform.localScale.y,
									 Boundaries.center.y+SpawnBox.transform.position.y+Boundaries.extents.y*SpawnBox.transform.localScale.y,
									 random);
		
		
		random = Random.value;
		LocalPosition.z = Mathf.Lerp(Boundaries.center.z+SpawnBox.transform.position.z-Boundaries.extents.z*SpawnBox.transform.localScale.z,
									 Boundaries.center.z+SpawnBox.transform.position.z+Boundaries.extents.z*SpawnBox.transform.localScale.z,
									 random);
	
	    // Return the world position
	    return LocalPosition;
	}
	
	// Best to generate them here, then you dont need a boolean to tell
	// if it has instantiated all of the "meshes"
	void Start () {
		Generate();
	}
	
	// if you are not accessing this from another Script, this should be a private function.
	public void Generate()
	{
	    for (int i = 0; i < NumOfStars; i++)
	    {
	        Instantiate(obj,SetBoxBoundaries(),Quaternion.identity);
	    }
	
	
	}
}

I have removed the “this” instance in your instantiate function and moved it to Start(). I have also included an easy random spawn function, that you can add functionability to if you want. This is what you do: Create two empty gameobjects. One that you drag your script on to, and one that you add a boxcollider to. In the inspector you drag your gameobject with your boxcollider to the “Spawn Box” field, and your object to spawn into the “Obj” field. You can scale and position your Boxcollider-object wherever you want, but you should not rotate it, i think.

The Update is, as described in the commend, called once per frame. So, Generate() is called also each frame !
And the i is reset to 0 on each call, so it don’t give you an real infinite loop but an action which is repeated 10 time per frame, which can become a lot of calls really really fast.
You would have to make the i variable one level upper in your code hierarchy to don’t have it reset each time you call generate.

I see two problems:

  1. Like others said Update is called once per frame so you get 10 instances per frame (at 60fps = 600 objects/sec)
  2. This might be the worst problem: You instantiate “this” which means the script itself which results in that the whole gameobject with this script is duplicating itself 10 times per frame. That means each of those new instances is doing the same!!! Now you have exponential growth (11(x-1)).

Example:

Frame 1 :       1 object
Frame 2 :      11 objects
Frame 3 :     121 objects
Frame 4 :    1331 objects
Frame 5 :   14641 objects

That’s why it looks like an infinite loop but actually you just spam the place with that many objects that instantiating takes damn long. Also you should run out of memory very quickly :wink:

If you want to instantiate something once at start, put it in Start and not in Update.

Second, you should think about what you actually want to instantiate. Cloning itself isn’t really a good idea. Also you placed them all at the same position (1,1,1) so you can’t see them.