I have implemented PoolBoss on top of an already implemented scene.
Some of the objects handled by the pool can be disabled in the scene at various times (but should not be returned to the pool when this is done). Then at some point I want to return one or more of the objects (which may or may not be active) to the pool, but the Despawn function doesn't complete on inactive objects (PoolBoss.cs:557), so they are never despawned.
I have disabled this check to get my scene working, but I was wondering if I'm just missing something and there is a better way of despawning inactive objects? It is not really an option to change the objects to always be active at the time of despawn.
Post by DarkTonic Dev on Sept 6, 2017 16:08:09 GMT
There is no way to despawn inactive objects. That's how we tell whether the object has already been despawned or not - sometimes it may be possible to accidentally get Despawn called more than once on the same object in the same frame, and we need the 2nd despawn to fail, so that the despawned count of that item is correct. By removing that code check, you risk having that not work properly.
1) Why can you not set the game object to active and immediately call despawn? 2) Why do you even need to despawn things if they're already inactive (and not taking any performance)? 3) Why would you need to deactivate game objects and not despawn them? You could instead set certain MonoBehaviors to inactive on the game object.
1) That would be a valid workaround (and it may just be the easiest way for me right now), but wouldn't that open myself up to the same problem as you describe? i.e. if I accidentally despawn an object twice (and set it to active before doing it), it would be counted wrong. The Poolboss check for active object would always return true if I always activate the object before calling despawn. 2) They still take up memory? Once I know I'm not gonna need them anymore, I think its better to clean up. 3) Isn't that akin to asking why you would ever deactivate an object and not just destroy it? :-) Inactive objects still keep their state, and can be changed/updated/referenced by other objects, and it is simpler to not have to recreate this state every time the object is needed.
I hope I don't come across as pedantic, but I think it is a bit dangerous to use a basic unity concept like a GameObject's active/inactive state to keep track of things like this. The purpose of deactivating an object seems to me that you don't want it to figure in all of Unity's automatic routines (Update, physics, etc) or be shown, but otherwise want to keep it around for some reason. While despawning to the pool means you're done with the object. I think the aim of an object pool like this should be to be as non-intrusive and make as few assumptions about other code as possible, to make it easy for users to integrate (and in all other regards, PoolBoss was very easy to get working!), so for something like this I would think some kind of dedicated counter for PoolBoss internal housekeeping would make sense. It's no big thing for me right now (I was mostly just unsure if I was using a wrong function when I asked the original question), and I will get my code working, but you might want to consider it in future updates?
Otherwise, PoolBoss works great for me and it was very easy to set up :-)
Post by DarkTonic Dev on Sept 7, 2017 16:05:35 GMT
#1, just make sure you don't enable an object that is already despawned. I assume your manager script that is doing this will know that info? #2, despawning something itself isn't going to save any memory. It's still sitting there disabled. If you respawn it later, yes that does. #3, yeah correct.
I can think of a way to allow you to disable objects and still despawn them, but we'd have to add another script to each spawned thing, which will adversely affect performance so I'm reluctant to do that on what is first and foremost a performance saving plugin. Myself, I just deactivate the script(s) that don't need to be running and keep the game object active.
Do you have a good idea on how to make it possible?
Note that you're the first person to voice this problem out of over 5,600 Core GameKit users, so people are either working around it or doing things as I am, but either way not seeing an issue here. I could go ahead and call out in the readme to not disable game objects or it's not despawnable just to avoid confusion, but that won't fix you.
Maybe have some kind of central lookup table (HashSet?) where the pool objects are added/removed when they are spawned/despawned? So instead of checking if the object is inactive, you check if it's in that table? I don't know if that would be feasible from a performance standpoint. My use case is probably a bit atypical, since I don't have that many pool objects and spawn/despawn rates are not very high (for me its mostly an issue of avoiding instantiate lag on mobile), but I guess many people are using it for much more intense spawn/despawn scenarios.
A notice in the readme would be nice, but maybe also a log message when it happens? The log feature you have is great for debugging, but I think it doesn't write a log in this instance, so when I noticed objects not despawning and enabled the logging it didn't help - I had to track the reason down in the code.
Actually, I just realized my problem was a bit different than described. The objects where I have the problem is not the objects themselves that are disabled, but actually a parent object. I tried changing your IsActive function to test for go.activeSelf instead of go.activeInHierarchy, and that actually fixed the problem for me. I dunno if that would be a viable solution?