Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Pool Kit - The ultimate system for pooling, spawning and despawning

Discussion in 'Assets and Asset Store' started by melgeorgiou, Jun 20, 2018.

  1. Mattitiyahoo

    Mattitiyahoo

    Joined:
    Dec 15, 2018
    Posts:
    7
    Hi!

    spawner.Pause() and spawner.Resume() are not doing the things I would expect based on their names :)

    Even though the spawner is "paused," it continues spawning prefabs at regular intervals.

    When I call Pause(), will the spawner "pause" it's count-down to the next spawn?

    For example, if there are 5 seconds left until the next spawn, and then I call Pause(), will it remain at 5 seconds until I call Resume(), at which point it will resume counting down like normal?

    Or does "pause" mean something else I'm unaware of?
     
  2. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @Mattitiyahoo,

    That seems strange.

    Please send me a PM / email with your invoice ID and I'll look into this for you first thing tomorrow ( as it's a little late over here in the UK! ). If you don't mind, can you also provide descriptions / screenshots of your spawner setup and any custom code.

    Thanks! :)

    - Mel
     
    Last edited: Jan 28, 2021
  3. Mattitiyahoo

    Mattitiyahoo

    Joined:
    Dec 15, 2018
    Posts:
    7
    So, the prospect of figuring out how to send you the most relevant code to my issue was intimidating.... I did not want to do it! (I am lazy).

    The heart of my issue (I think) is this: I wanted to pause the entire game, but I did not want to set the Time.timeScale to Zero because that caused my pause menu to not play sounds (kinda janky). (I think your Spawner system uses Time.timeScale, right?)

    But I figured out something that works, so I'd like to share it!

    I created two classes in your project in a new namespace called HellTap.PoolKit.Custom

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace HellTap.PoolKit.Custom
    4. {
    5.     public class WaitForUnpausedSeconds : CustomYieldInstruction
    6.     {
    7.         private float _time;
    8.  
    9.         public override bool keepWaiting
    10.         {
    11.             get
    12.             {
    13.                 return KeepWaiting();
    14.             }
    15.         }
    16.  
    17.         public WaitForUnpausedSeconds(float time)
    18.         {
    19.             _time = time;
    20.         }
    21.  
    22.         private bool KeepWaiting()
    23.         {
    24.             if (!Pause.Paused)
    25.             {
    26.                 _time -= Time.deltaTime;
    27.             }
    28.  
    29.             return _time > 0;
    30.         }
    31.     }
    32. }
    33.  
    Code (CSharp):
    1.  
    2. namespace HellTap.PoolKit.Custom
    3. {
    4.     public static class Pause
    5.     {
    6.         public static bool Paused;
    7.     }
    8. }
    I modified your code in 4 places like this:

    Code (CSharp):
    1.                     // If we're using a countdown timer, do that here
    2.                     if( spawnDuration == SpawnDuration.CountdownTimer ){
    3.  
    4.                         // Subtract from the countdown every frame
    5.                         if ( _durationCountdownCurrent > 0){
    6.                             // Custom code only tick if not paused
    7.                             if(!Custom.Pause.Paused)
    8.                                 _durationCountdownCurrent -= Time.deltaTime;
    9.                      
    10.                         // When we're finished, run the CheckIfSpawnerIsFinished() method to stop spawning
    11.                         } else {
    12.                             CheckIfSpawnerIsFinished();
    13.                         }
    14.                     }
    Code (CSharp):
    1.                     // If we're using a countdown timer, do that here
    2.                     if( spawnDuration == SpawnDuration.CountdownTimer ){
    3.  
    4.                         // Subtract from the countdown every frame
    5.                         if ( _durationCountdownCurrent > 0){
    6.                             // Custom code only tick if not paused
    7.                             if(!Custom.Pause.Paused)
    8.                                 _durationCountdownCurrent -= Time.deltaTime;
    9.                      
    10.                         // When we're finished, run the CheckIfSpawnerIsFinished() method to stop spawning
    11.                         } else {
    12.                             CheckIfSpawnerIsFinished();
    13.                         }
    14.                     }
    Code (CSharp):
    1.         IEnumerator Start () {
    2.             // Loop through the Prefabs and set them up
    3.             for(int i = 0; i < prefabs.Length; i++ ){ prefabs[i].Setup(); }
    4.  
    5.             // Setup values
    6.             _durationCountdownCurrent = durationCountdown;
    7.  
    8.             // Start the spawner automatically at start
    9.             if( spawningBegins == StartMode.AutomaticallyOnStart ){
    10.                 RestartAndPlay();
    11.          
    12.             // Start after delay
    13.             } else if( spawningBegins == StartMode.AutomaticallyOnStartAfterDelay ){
    14.                 // Custom code WaitFurUnpausedSeconds instead of WaitForSeconds
    15.                 yield return new WaitForUnpausedSeconds( autoSpawnDelay );
    16.                 RestartAndPlay();
    17.             }
    18.  
    19.         }
    Code (CSharp):
    1.         void OnEnable(){
    2.  
    3.             // Register this spanwer with PoolKit
    4.             PoolKit.RegisterSpawner(this);
    5.  
    6.             // Start the spawner automatically at start
    7.             if( spawningBegins == StartMode.AutomaticallyOnEnable ){
    8.                 RestartAndPlay();
    9.          
    10.             // Start after delay
    11.             } else if( spawningBegins == StartMode.AutomaticallyOnEnableAfterDelay ){
    12.                 StartCoroutine( OnEnableAfterDelay() );
    13.             }
    14.         }
    15.         // We seperate this out into an IEnumerator to apply the delay
    16.         IEnumerator OnEnableAfterDelay(){
    17.             // Custom code WaitFurUnpausedSeconds instead of WaitForSeconds
    18.             yield return new WaitForUnpausedSeconds( autoSpawnDelay );
    19.             RestartAndPlay();
    20.         }

    Those are the only places I made changes in your code.

    In my code, to pause your spawner, I do this:
    Code (CSharp):
    1. HellTap.PoolKit.Custom.Pause.Paused = _paused;
    That achieved my desired affect :)

    I hope this is useful to you! And thanks again for your willingness to help!
     
  4. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @Mattitiyahoo,

    No problem! :)

    I'm still not exactly sure why pausing the spawner normally wouldn't work for you. Anyway, I'm glad to hear you were able to address the issue in this edge case with your own custom code ( thanks for sharing btw! )

    In a future update I'll see if I can reproduce the issue you were having and come up with a native solution :)

    - Mel
     
  5. knas01

    knas01

    Joined:
    Feb 24, 2018
    Posts:
    236
    Hi, I'm curious how much resources a clone use compare to the original. Is it really a big deal to have a few more instances created just to be safe or should you absolutely try to minimize the amount? I'm talking about prefabs that contain up to 100 objects and 100k+ verts. Just the prefab file is 200kb and this is for PC.
     
  6. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @knas01,

    There are a lot of factors that can have an impact. Generally speaking, if you have a few extra prefabs in the pool ( and assuming you have the memory to spare ), this shouldn't cause much of an issue. Things only need to be rendered if they are active ( spawned from the pool ) so the only thing that is happening is a bit of overhead needed for Unity to store the objects in memory and to keep track of it in the game, etc.

    It is always best to not use what you don't need and there are always edge cases. However, in the situation you describe it is probably not worth stressing too much over if you're not quite sure exactly where that instance limit should be. A few extra instances should be fine! :)

    I hope this helps! :)

    - Mel
     
  7. knas01

    knas01

    Joined:
    Feb 24, 2018
    Posts:
    236
    @melgeorgiou Thanks for the explanation, very good.

    When it becomes more relevant in the future when the project is larger, is there a feature to create a breakpoint when the pool runs out of instances?
     
  8. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @knas01,

    There isn't a native feature for that ( at least not yet lol ).

    Currently you'll just get nothing back if you exceed the limits ( it will return null ). So you could easily implement your own breakpoint by doing a null check on your spawned item :)

    After spawning myInstance, add something like:

    if( myInstance == null ){ Debug.Break(); }

    That should pretty much do it :)

    Hope that helps!

    - Mel
     
  9. knas01

    knas01

    Joined:
    Feb 24, 2018
    Posts:
    236
    Thank you.
     
  10. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    You’re welcome! :)

    - Mel
     
  11. lorewap3

    lorewap3

    Joined:
    Jun 24, 2020
    Posts:
    58
    Hi @melgeorgiou ! I just purchased PoolKit this afternoon. It's very extensive and so far I'm very impressed!

    I have a question regarding the "Wait For Particle System To Finish" option of the Automatic Despawning. My use case is fairly simple. I have particle system prefabs that trigger one-shot particles when musical notes hit (using Koreographer). I have a few FX asset packs I'm using for the particle effects. In order to reorient the particle prefabs to the rotation I want, I add a blank gameobject as a parent to the particle systems. Because of this it seems the automatic despawning doesn't work because the topmost gameobject doesn't have a particle system on it. If I remove that blank parent, it despawns as expected, but the orientation is all wrong.

    Is there a way to get the functionality I'm after? I want the instance to despawn when the particle systems are finished, but be smart enough to ignore gameobjects in the prefab that don't have particle systems attached. (Mainly just the topmost parent). You maybe thinking "why don't you just set a fixed rotation in the spawner"? Because the spawners themselves rotate. (They're attached to 2D character extremities)

    Or is there something obvious I'm missing? I'm not sure of a better way to re-orient these prefab outside of parenting them without tweaking all the individual particle systems within.

    Thanks Mel!
    Will
     
    Last edited: Feb 19, 2021
  12. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi Will,

    Firstly, thanks for purchasing PoolKit - much appreciated! :)

    Usually I ask people to PM / Email me with their invoice IDs but as this is an easy one that may help others, I'll just ask that you send it next time :)

    Anyway, on to your fix...

    Easiest way is to not use Automatic Despawning on the Pool level because that doesn't quite fit your purposes. If you know roughly the time it takes for the particle to finish, you could just use a countdown timer instead which would pretty much accomplish the same thing :)

    If you REALLY want to track the particle system directly with the setup you have, you need to put a 'Despawner' component on your particle system prefab. Then choose "Despawn This GameObject >> After Particle System Finishes", followed by "Use the Particle system >> On Another GameObject". This will allow you to drag and drop the particle system from the child gameobject into the slot below.

    Example:

    PoolKit Setting Up Particle System Despawner.png

    Save the prefab and you should be good to go!

    Hope this helps! :)

    - Mel
     
  13. lorewap3

    lorewap3

    Joined:
    Jun 24, 2020
    Posts:
    58
    Hi @melgeorgiou ! Thanks for the assistance that was exactly what I needed! I sent you a PM with my order number as I will undoubtedly have more questions ;)

    I do have a small one that others might have as well.

    I implemented your solution, which works, but I'd like you to clarify something. I put only a single particle system component in the "Particle System To Use" slot as that's all it allows. This maybe a particle system question rather than dealing with your asset, but is this guaranteed to despawn only after all of the child particle systems have finished? I have my empty gameobject with the despawner on it, and it's only child is a particle system, which is what I put in the 'Particle System to use' field above. However, that child particle system has 3 child gameobjects that all have particle systems on them. Is this method guaranteed to wait for all of them to finish?

    I assume that the countdown method is likely the most performance option? I have a large number of particle prefabs I'm going to use, and I wanted the logic to be smart enough that I wouldn't have to set manual countdown timers for possibly 100 prefabs. However, if it's a huge performance hit to check for the particle system to finish on every frame rather than a countdown, it'd probably be a worthwhile time investment. I guess I'm asking for your opinion on what you would recommend. In my test case the statistics are showing around 144 instances were created to keep up with the spawning needs. That number is likely to keep increasing. Would you be able to educate me on how much of a performance cost this dynamic despawning is compared to the manual timer?

    Thanks again Mel!
    Will
     
  14. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi Will (@lorewap3),

    Thanks for sending over your PM :)

    1) I believe this depends on whether your particles are setup correctly with child systems, etc. Although off the top of my head I'm not 100% sure.

    2) Yep, if you can get away with automatic despawning using a countdown, I would say you'd have a slight optimisation there because all of the automatic-despawners are processed in one loop. The overhead for the full-powered despawner components isn't large by any means, but with high enough instances ( hundreds as you mention ) it *may* get to a point where the difference is more apparent :)

    Hope that helps! :)

    - Mel
     
  15. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi everyone,

    POOL KIT v3.0.2 IS NOW LIVE!

    PoolKit v3.0.2 is now LIVE on my site and should be approved soon on the asset store!

    IMPORTANT: ALWAYS BACKUP YOUR PROJECT BEFORE UPDATING!

    This update fixes a small bug when despawning 2D physics events along with the countdown option also enabled.

    Thanks to everyone who has purchased PoolKit so far! :)

    - Mel
     
    NikoBay likes this.
  16. rxmarccall

    rxmarccall

    Joined:
    Oct 13, 2011
    Posts:
    353
    Hello, I wanted to ask if this asset will eventually support Addressables?
    Addressables / Asset Bundles are a huge performance saver and I'm having a hard time finding pool managers that support them :/
     
  17. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @rxmarccall ,

    I'll be looking very closely into addressables for PoolKit 4.0 ( which will be a free update as usual ). It is the top requested feature so hopefully I'll find some interesting ways to implement it. No firm release date on that yet, though.

    Hope that helps! :)

    - Mel
     
    NikoBay and rxmarccall like this.
  18. trueh

    trueh

    Joined:
    Nov 14, 2013
    Posts:
    74
    Hi. I am making a loading screen and I would like to know if there is a way to know that PoolKit has finished instantiating all the prefabs declared in a pool. It would also be useful to know any value which can be used to calculate instantiation progress.

    Thank you. Pool Kit is really nice.
     
  19. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @trueh,

    I'm glad you like PoolKit! :)

    Currently ( and off the top of my head ) I believe that PoolKit should be ready by the time Start() runs in the scene. This means that in most cases it should work as soon as the scene starts.

    If you want to play it safe, one way you could do it is instantiate the pool then wait a couple frames ( you could easily use coroutines for this and ' yield return 2' ) and everything should be ready like that.

    The only potential issue there is if you are using 'lazy preloading' which of course would create the instances over a longer period of time. To handle that you may need to use the Pool.GetInstanceCount() API and compare with the expected number of instances to load which may be somewhat trickier so I would recommend turning lazy preloading off in your use-case just to make it easier for you.

    However, this is an interesting point so I'm going to add a built-in API to easily know when the pool is ready when PoolKit 4.0 is ready :)

    Hope this helps!

    - Mel
     
    Last edited: Jun 11, 2021
  20. trueh

    trueh

    Joined:
    Nov 14, 2013
    Posts:
    74
    Thank you very much!
     
  21. trueh

    trueh

    Joined:
    Nov 14, 2013
    Posts:
    74
    Hello:

    I wonder if you could also consider including a feature for Despawners in PoolKit 4.0. I have create my own component to despawn objects going out of the viewport. My use case is for a 2.5 sidescroller. Shots are being despawned once their visible bounds get out of the viewport to prevent impacts on enemies which are not visible. It also allows saving a couple of bullet instances in the pool as well as saving some CPU cycles.

    Thank you.
     
  22. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @trueh,

    That sounds like it could be a cool idea. Could you PM / email me a code snippet of how you're currently approaching this and I'll see if I can come up with some ideas to streamline it into the Despawner :)

    Thanks! :)

    - Mel
     
  23. trueh

    trueh

    Joined:
    Nov 14, 2013
    Posts:
    74
    PM sent. Thank you!
     
  24. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    @trueh,

    No worries! :)

    - Mel
     
  25. lorewap3

    lorewap3

    Joined:
    Jun 24, 2020
    Posts:
    58
    Hi @melgeorgiou !

    Poolkit works great I have no complaints, but I would like to pick your brain about something.

    I'm using Poolkit mostly for particle system prefabs. The despawner attached to the prefab waits for the particle system to finish and then despawns. The spawner uses the local transform to drive the scale/rotation/position of the spawns. Nothing special just normal usage.

    The next step I want to do, though, is to drive the color settings of the particle system itself as well when spawned. This is more complicated and I'll need to do a custom solution. I read up on the spawner events and the OnSpawnerSpawn seems what I'll need. But I'm not sure. If I hook into this event, at what point do I get the instance? The particle systems inside the prefabs are set to play automatically. I'm assuming this is in the Awake method since it's labeled as 'Play On Awake'. I'm trying to ensure the particle system doesn't actually play until I've made the color adjustments. If I hook into that event, will that work? I get the instance, update all the colors in the particle systems, and then it will play correctly using the colors I set? Afterwards, then, they will need to be reset. But more likely the pooled prefab can just retain those color settings until used again and they are set upon instantiation.

    I guess my other concern is the line in the documentation that says "Please note that using this excessively may have an impact on performance" lol. Yes it does say "excessively", but I'm still curious about this performance hit.

    My project is more a content creation tool than a game. These spawns are particle systems that trigger based on musical notes (using Koreographer) and there will be alot of them at a time. (I got to 36 max current spawns on one character alone) I guess I'm wondering if it's better to do this as a push method where I update the particle systems manually each spawn, or whether I add a component in those prefabs themselves to pull the colors from the central color palette.

    I'm hoping to hear from the expert himself :) . Any advice you have is most appreciated!
    Thanks!
    Will
     
  26. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi Will (@lorewap3 ),

    Firstly, I'm glad you're happy with PoolKit!

    There's actually quite a few ways to approach what you're doing :)

    You could use OnPoolSpawn or OnSpawnerSpawn but it seems to me you don't really need to access the pool or the spawner to achieve what you're doing. Unless I'm missing something, you could literally just use Unity's OnEnable and OnDisable methods instead.

    When PoolKit spawns an instance, the GameObject is re-activated which will fire off Unity's OnEnable method on any custom MonoBehaviour scripts you add to your Particle GameObject. When it is despawned, the GameObject will be made inactive which will fire off the OnDisable method. You don't need to track the pool or the spawner if you're just waiting for those hooks to modify your particle system :)

    So, to achieve what you're doing, I would try making a script that has OnEnable() and OnDisable() methods and attach it to your particle GameObject. Then, you can simply change the attached particle system in either OnEnable or OnDisable - depending on what makes the most sense for your game ( or both! ).

    As for performance, that warning is more for when you're hooking into UnityEvents for callbacks rather than scripting via delegates or PoolKit listeners ( which is crazy fast ). UnityEvents have quite a bit of extra overhead but they're included because of their ease of use and to help new users ( in most cases its probably fine ). In any case, the approach I've outlined above avoids the need for any callbacks at all so that wouldn't apply to you anyway :)

    I hope this helps! :)

    - Mel
     
  27. Cannabik

    Cannabik

    Joined:
    Jan 11, 2018
    Posts:
    7
    Hi @melgeorgiou!

    I'm using PoolKit to do pretty basic things, but I'm a bit confused as to how I could do something simple like this:

    Code (CSharp):
    1. // Get the object instatiate
    2. GameObject tmpObj = Instantiate (projectilePrefab, startPoint, Quaternion.identity);
    3.  
    4. // Do something with this
    5. object tmpObj.GetComponent <Rigidbody2D> () .velocity = etc

    I need to activate the spawner through a script and take the object (clone) to change certain parameters.

    With mySpawner.Play () I can make it activate whenever I need to, but I don't see how I can get the instantiated object.

    Thank you for your attention and sorry if my English is not very clear.
     
    Last edited: Jul 16, 2021
  28. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @Cannabik,

    For support requests, can you please send me a private message / email ( along with your invoice ID so I can verify your purchase ) and I'll be happy to help! :)

    - Mel
     
  29. Cannabik

    Cannabik

    Joined:
    Jan 11, 2018
    Posts:
    7
    No problem!

    I have sent the Invoice ID by mail :)
     
  30. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @Cannabik ,

    Thanks! I've replied over there :)

    - Mel
     
  31. Rockaso

    Rockaso

    Joined:
    Oct 31, 2016
    Posts:
    85
    Hello, I bought your asset but I don't understand how to do something simple as Spawning and Recycling from script.
    The documentation seems to resolve around Spawners to make use of your pooling techniques, but I don't need a spawner. I need to be able to actually do pooling from code =/
     
  32. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @Rockaso

    Firstly, thanks for your interest in PoolKit!

    The good news is you certainly can spawn directly from a pool and not a spawner, and it works much like the built in Instantiation code - you just need to use the right pool! :)

    BTW: The PoolKit Documentation PDF covers this in a lot more detail from page 52 onwards and you can also check out some of the example scenes in the package to see how things are working! :)

    To get you started, first you need to cache the pool containing the prefab you want to spawn. Then, you simply replace your Instantiation calls with pool.Spawn(). Let's take an example of spawning an enemy... We'll assume you've already setup a PoolKit Pool named "Enemies" and it includes the prefab "enemyPrefab".

    Instead of this:

    Code (CSharp):
    1.  
    2. // Prefab of the enemy (setup in inspector)
    3. public GameObject enemyPrefab = null;
    4.  
    5. /// ------------------------------------------------------------------------
    6.  
    7. // Normal Instantiation Elsewhere In Code
    8. GameObject enemyInstance = Instantiate( enemyPrefab, transform.position, transform.rotation );

    You would do this:

    Code (CSharp):
    1.  
    2. // using HellTap.PoolKit;
    3.  
    4. // Prefab of the enemy (which should also exist in the "Enemies" pool!)
    5. public GameObject enemyPrefab = null;
    6.  
    7. // Cache the pools we need at Start so we don't need to look for it every time
    8. Pool enemiesPool = null;
    9. void Start(){ enemiesPool = PoolKit.GetPool( "Enemies" ); }
    10.  
    11.  
    12. /// ------------------------------------------------------------------------
    13.  
    14. // Replace Instantiation with the Pool's Spawn method
    15. GameObject enemyInstance = enemiesPool.Spawn( enemyPrefab, transform.position, transform.rotation );
    16.  
    17. // Make sure a new instance was returned
    18. if( enemyInstance != null ){ /* ... Do Stuff ... */ }
    19.  
    20.  

    NOTE: It's usually a good idea to add a null check right after spawning as you may run out of instances depending on how you've setup the pool ( and it would return null instead of a GameObject / Transform ).


    If you want to Despawn ("recycle") an object back to the pool rather than destroy it, you will need to use the Pool that contains it to do that as well. Like this:

    Code (CSharp):
    1. // Tell the enemiesPool to despawn the enemyInstance
    2. enemiesPool.Despawn( enemyInstance );

    I hope this helps! :)

    - Mel
     
    Last edited: Aug 1, 2021
  33. Rockaso

    Rockaso

    Joined:
    Oct 31, 2016
    Posts:
    85
    thanks for the response,
    The key was to know about "Spawn" and "Despawn", which are methods inside the Pool.

    Your asset is amazing.
    It was what I was looking for.

    Thank you
     
    melgeorgiou likes this.
  34. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
  35. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
    Will that Pack come on a sale?
     
  36. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
  37. Pandur1982

    Pandur1982

    Joined:
    Jun 16, 2015
    Posts:
    275
    Thank you for your answer, at the moment iam working on a Turorial Series on Youtube can see here :
    , in that series i use Assets from the Asset Store and tell my Viewer what is good to buy and what not, with Link for the Asset in the Asset-Store. So i think later we came on a Point how we need a Pooling System so i wait for a Sale then and test it out.

    Bye Sissel
     
  38. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @Pandur1982,

    Sounds good - if you have any questions about PoolKit, feel free to send me a PM :)

    - Mel
     
  39. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    Hello @melgeorgiou

    I've sent an email, but i'll ask here too.

    I'm interested in buying the Pool Kit and i have question for you before that.

    I'm using another pooling asset and i'm not satisfied with it since i'm currently porting my game for consoles and the performance is lackluster. The main issue i have is that the (what you call "preloading") creating instances over time is not working properly. It just initializes for a set number of frames and then dumps all the items in the same frame causing a huge instantiation and GC spike after the "initialization" is done.

    Does your asset really creates items over time (for example, 5000 items over 1000 frames will actually instantiate 5 items per frame in the hierarchy) and if so is there a limit to it since i need some long times (in some cases up to 5000-6000 frames for around 1000 items) and can i use the instantiated items before the whoole pool of items is batched?
     
  40. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    HI @Oshigawa

    Firstly, thank you for your interest in PoolKit :)

    Yes, it can instantiate pretty much any number of objects you want over any time frame. You set an optional initial delay, how many objects to instantiate per pass, and the time delay between passes ( it uses time rather than frames but you can just use a really small number for it to effectively become a frame ). So it will keep creating objects until you have created the total number of objects you've told it to.

    It is possible to access the instantiated objects before lazy preloading completes (provided your pool is setup correctly, etc ). If you try to spawn too many objects too soon, PoolKit will return a "null" object indicating you've run out of instances.

    However, it's worth noting that creating this many objects in this way is bound to cause a performance hit ( each instantiation causes a memory allocation which is unavoidable ), so this would be suitable for something like a loading screen but not actually during core gameplay.

    Hope this helps! :)

    - Mel
     
  41. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    Hello Mel,

    Thanks for the quick response. That's exactly what i needed, off to buy it ;)
     
  42. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
  43. lorewap3

    lorewap3

    Joined:
    Jun 24, 2020
    Posts:
    58
    Hi @melgeorgiou !

    I was wondering if I might ask for your expertise on something? It maybe a more basic unity question about pooling than perhaps Poolkit specifically, but I can't think of a better person to ask! So thank you in advance!

    I'm using Poolkit for a pretty standard purpose of pooling particle prefabs. Standard stuff. What I'm trying to do is improve the workflow with some custom editors. I already have one for updating the particle prefab. So assuming no pooling was used and standard instantiating was all that was happening, there wouldn't be an issue.

    I'm wanting to tweak the prefab using my custom editor during play mode and have all those pooled gameobjects update as well. Not to overcomplicate the question, lol, but I set up an event delegate to handle that dynamic update. So I know how I'm going to make the updates, my question is regards with how/when to hook into those events.

    Currently I'm hooking into the event in a 'ParticleIdentity' monobehaviour on the instantiated particle gameobjects during the Awake method. This seems to work fine hooking into the events. The unhook part is in OnDestroy. The main point is that I can't do this OnEnable and OnDisable as doing so would miss all the events that happen while the pooled gameobject is disabled.

    I guess what I'm asking is are there any gotchas doing it this way? I only want them to hook/unhook once, when the gameobjects are initially pooled and when they are destroyed. I'm trying to think through all the scenarios of it being enabled/disabled constantly and all the while not missing changes I'm making in my custom editor.

    Do you have any thoughts on this? Can you think of any situations where an extra hook or unhook would happen and mess things up?

    Edit:
    Or maybe there's a Poolkit API to hook into? The Pool itself component has a event hook to execute on each gameobject as it's pooled and then unhook when removed?


    Thank you so much for your expertise Mel! It's much appreciated!

    Thanks,
    Will

    [PS:
     
    Last edited: Mar 8, 2022
  44. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @lorewap3,

    As this is a very specific question, would you mind sending me a PM / Email along with your invoice ID and I'll get back to you tomorrow ( its a little late over here in the UK! :) ). Thanks!

    - Mel
     
    Last edited: Mar 9, 2022
  45. lorewap3

    lorewap3

    Joined:
    Jun 24, 2020
    Posts:
    58
    Hey Mel, I had done so back on Feb 20 of last year, but I replied to it so it should pop up for you.

    -Will
     
    melgeorgiou likes this.
  46. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Thanks Will, replied to PM! :)

    - Mel
     
  47. Notso

    Notso

    Joined:
    Oct 25, 2015
    Posts:
    44
    Have you updated this to use the new Unity pooling methods as well introduced in 2021.x?
    Are they more efficient or the same as your methods? (More difficult to use than an asset for a beginner-intermediate coder though)
    Also is there a way to reset the prefab used? so say you have a lot of vars/scripts on an AI that change when being used and then when sent back to the pool reset on respawning? (like health, body damage, turning scripts backon that were disabled during its lifetime in play mode).
     
  48. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @Notso,

    Firstly, thanks for your interest in PoolKit! :)

    I'm fairly sure PoolKit will beat out the default Unity pooling methods when the entire feature set is taken into account. I haven't done a direct speed comparison but I highly doubt it can beat PoolKit's system ( especially the Fixed Array pooling type - In C# there is no faster way to access objects as far as I'm aware! ). Unique features like chain-spawning take pooling to the next level :)

    It's worth noting that the PoolKit UI took longer than the base code to create because I intentionally wanted to create the most easy to use system possible. Even though I'm obviously biased, PoolKit is the only solution I use in my own projects :)

    The easiest way to reset your prefab in code is to simply add an OnDisable method ( or OnEnable ) to your GameObject and do it there. These will fire automatically but you can also use PoolKit's super fast OnSpawned methods if you need a custom implementation. There are loads of other options and approaches you can use too! :)

    Hope this helps! =)

    - Mel
     
  49. Notso

    Notso

    Joined:
    Oct 25, 2015
    Posts:
    44
    Thanks for the quick reply. Guess I will have to deal with the GC of just basic destroying/spawning. I have way too much on each AI to go through and reset. I have a pooling system already, your UI is way better laid out and has a lot more options. (I currently use purepool) But not sure I need even that since the only thing I am pooling now is bulletholes.
     
  50. melgeorgiou

    melgeorgiou

    Joined:
    Nov 3, 2012
    Posts:
    768
    Hi @Notso,

    No worries! If you need to start pooling / spawning more advanced setups in future feel free to give PoolKit another look! :)

    - Mel