What causes the following to slow down after a few minutes, and how should it be corrected?
using UnityEngine;
using System.Collections;
public class HelloWorld : MonoBehaviour {
public GameObject cubePrefab;
// Use this for initialization
void Start () {
print("Hello World!");
}
// Update is called once per frame
void Update () {
Instantiate(cubePrefab);
}
}
You are instantiating a prefab in each and every frame. So it could just like that instantiate 30-60 gameobjects every second or more.
After a few minutes the memory usage has substantially grown so that new memory allocation for newer prefab instantiations takes longer (also because processor time is reserved for each and every instantiated gameobject, therefor each frame takes more time, whether that time grows by a lot or not depends on the prefab and the scripts on it) until memory for your scene is full and your scene (and therefore Unity) will crash.
You are creating an object each frame. If you are running this at 60 frames per second, that is, 60 calls to Update per second, after 10 minutes you will have :
60 objects/sec x 60 secs/min x 10 mins = 36000 (36 thousand! objects)
If your framerate is not locked to 60 (via vsync in the quality settings or Application.targetFramerate), then this can be even greater.
You could limit it using a counter:
public class HelloWorld : MonoBehaviour {
public GameObject cubePrefab;
public int totalNumberOfOjects = 10;
private int objectsInstantiated = 0;
// Use this for initialization
void Start () {
print("Hello World!");
}
// Update is called once per frame
void Update () {
if(objectsInstantiated < totalNumberOfOjects) {
Instantiate(cubePrefab);
objectsInstantiated++;
}
}
}
The public variable totalNumberOfOjects will hold how many objects you want to instantiate and it will be visible in the inspector, so that you can change it’s value in the Editor. The private variable objectsInstantiated will count how many objects have been created and used as a gate to stop creating more when the total number is reached.
@Update: An alternative as pointed out by InvicibleCat would be to Instantiate them all using a for loop, in your Start method:
public class HelloWorld : MonoBehaviour {
public GameObject cubePrefab;
public int totalNumberOfOjects = 10;
// Use this for initialization
void Start () {
for (int i = 0; i < totalNumberOfOjects ; i++){
Instantiate(cubePrefab);
}
}
}
In this last example all the objects are instantiated in the same frame, compared to one object per frame (Update) in the first example.