So, on my current project I am using object pooling to cause enemy NPCs to create powerups on death. This isn’t troublesome in my dev builds, but in the Editor I get spammed with unhandled clones. I’ve been working on ways to get rid of them, specifically this little script that is on an object that persists across scenes:
using UnityEngine;
using System;
using System.Linq;
using System.Collections.Generic;
public class CloneKiller : MonoBehaviour
{
#region Variables / Properties
public bool DebugMode = false;
public string CloneNameFragment = "(Clone)";
#endregion Variables / Properties
#region Engine Hooks
public void OnLevelWasLoaded()
{
RemoveAllClones();
}
public void OnApplicationQuit()
{
RemoveAllClones();
}
#endregion Engine Hooks
#region Methods
public void RemoveAllClones()
{
if(DebugMode)
Debug.LogWarning("Looking for all game objects with " + CloneNameFragment + " in their name, and destroying them!");
IEnumerable<GameObject> allGameObjects = (GameObject[]) GameObject.FindObjectsOfType(typeof(GameObject));
IEnumerable<GameObject> clones = allGameObjects.Where(o => o.name.Contains(CloneNameFragment));
foreach(var currentClone in clones)
{
Destroy(currentClone);
}
}
#endregion Methods
}
While this code works great for killing clones of powerups on scene change, there’s one problem - it dosen’t handle powerups created as a result of the app closing, and thus destroying all enemies that spawn powerups.
I have a feeling I am approaching this problem from the wrong angle. What can I do to ensure that these cloned powerups are properly destroyed on quitting the application?
You can use a flag so that the enemies will know when they can or can not spawn power ups, or use a different destruction method for each situation, instead of directly destroying a clone (i.e KillClone method spawns powerups, RemoveClone not).
A few things I don’t get, is how your powerups not destroyed when you quit your application are a problem. I mean, the application has closed, right? Also, usually a problem that happens in editor (assuming correct scene flux) is more likely to happen on builds - except that maybe the side effects are others. If this is the case, the presence of the CloneKiller class is kludge to solve a problem caused by logic in another place.
Some things that may help us in understanding the problem: are the clones or powerups persistent objects? What exactly is the resulting problem? The game is hanging? Too long loading times?
The exact problem I am trying to solve is that, in the editor when I stop playback, a bunch of cloned powerups are spawned. I previously noticed this happening on level change as well, but this script removed that problem. It’s not that the clones are persistent at all; upon a level being loaded, or the app exiting, all game objects are destroyed. I think the true problem is that, as you say, I have not provided a way to tell my item-spawning objects to not spawn things at certain times.
But you got me thinking…maybe I can do something like this on my Item Spawner:
public bool CanSpawnItems = true;
public void OnApplicationQuit()
{
CanSpawnItems = false;
}
public void OnDestroy()
{
if(! CanSpawnItems)
return;
// ...Existing logic...
}
…I can just couple that with my Scene Transition script radiating a command to all game objects to not spawn powerups anymore, thus making this class unnecessary.
I’ll give this a shot…as I said in my original post, I think I’ve been going at this from the wrong angle!
Indeed - it seems like setting a flag to check is the “accepted” way of doing it. Looking at the Unify community wiki on singletons, it seems to be using the “applicationIsQuitting” flag to deal with the same issue you’re seeing.