- Home /
Why does this coroutine freeze my game?
I'm using a coroutine to manage NPC spawns, and it seems to my eyeballs that it runs and yields correctly, but every time I run the game it freezes up after a few seconds, and disabling this coroutine results in it no longer freezing. Do I have an obvious mistake in my implementation?
void Awake(){
StartCoroutine (managePedestrianPopulation());
}
IEnumerator managePedestrianPopulation(){
while (true) {
SpawnPedestrian(); //Check actual population density vs. desired population density, spawn new ones if under, remove old ones if way over
yield return new WaitForSeconds(2f);
}
}
void SpawnPedestrian(){
if (activeSpawners.Count > 0){ //If there are any active spawners in the game
int randomIndex = Random.Range (0, activeSpawners.Count); //Select a random spawner from the list of active ones
Transform newPedestrian = PoolManager.Pools ["Pedestrians"].Spawn ( //Pooling system: grab a pedestrian prefab from my pool and spawn it at the spawner selected above
pedestrianPrefab,
activeSpawners[randomIndex].t.position,
Quaternion.identity
);
}
}
$$anonymous$$y eyeballs agree, but they may need a checkup. :)
Have you considered that it may be the actual spawning of the pedestrians that's causing the issues? For example, if they spawn on top of each other, do you have tons of collisions? $$anonymous$$aybe try calling SpawnPedestrian a couple dozen times in Awake()?
A tertiary cause rooted in pedestrians spawning might be the problem, but in playing around a bit I'm having a heck of a time reproducing the freeze without a coroutine- pedestrians spawn one at a time, once every two seconds, and they're only fitted with one capsule collider each, so there shouldn't be enough raw physics interactions to overpower the system. I can't tell for sure, but experimentation also seems to suggest that it freezes the moment managePedestrianPopulation() gets called- I can run this with only one spawn point, and my eyes glued to it, and it will still freeze before any pedestrians pop in.
On a related note, one thing making me suspect the coroutine, and not the spawner, is that I've been able to manually spawn hundreds of pedestrians at a time without hiccups or weirdness, it wasn't until I started experimenting with ways to make it automatic that I had problems.
Answer by Addyarb · Nov 22, 2014 at 03:33 AM
It's the while loop. Change it to if (or if and else). Happened to me all the time until I realized that you can only use while loops in very specific situations.
i.e. ->
if (true) {
SpawnPedestrian(); //Check actual population density vs. desired population density, spawn new ones if under, remove old ones if way over
yield return new WaitForSeconds(2f);
}
Okay, that is weird. This fixes the freeze, but I can't for the life of me figure out why... would you $$anonymous$$d expanding on the technical reasons behind why a while(true){} freezes coroutines? :)
Also, is there a way to make this loop with the if? I need it to run every 2-ish seconds, but with if true, it appears to only run once.
while(true) is perfectly acceptable to use in coroutines, as long as there is a yield inside the loop. Your code has this in place.
The normal cause of a freeze is an infinite loop. But its not in this code.
This code does not happen to be attached to the pedestrian prefab by any chance? If every pedestrian is running this code, then you get an infinite loop through each pedestrian spawning a new pedestrian as soon as its created. This code should be off on its own on a manager type GameObject
Nope, it's attached to a single, empty gameobject I use to hold logic controllers.
That's very strange then. Your original code should have worked as written. Without seeing your project I can't really offer much more constructive help on this.
Quick question, does using the if actually produce the desired behaviour? ie do you get a random spawn every two seconds?
I removed the accept state on this answer since the answer doesn't make much sense. As Bored$$anonymous$$ormon said it's perfectly fine to use a while loop like this in a coroutine.
There are a lot of other possible causes for a freeze. What about your pool manager? What does it do when it runs out of pooled objects?