Announcement

Collapse
No announcement yet.

Plugin Object Pool Component

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    [SUBMITTED] Plugin Object Pool Component

    UPDATE:
    ----------
    [PLAYABLE DEMO]
    [DEMO PROJECT 4.15]


    Marketplace released with official support for these platforms:


    [available here, click image]:

    ----------

    Hey guys, here to talk this new toy I've got here; I had to find a way to workaround the impact on FPS when creating many many bullets for a project.
    Long story short: I've ended up building an Object Pooling system and ultimately turning the solution into a self-contained plugin. I'm very satisfied with the results so here I am sharing with you, please take a read


    So... This is not just a simple script to hide/show actors.
    The classes implemented by this plugin builds for you a fully working Object Pool system super easy to use.
    It's blazing fast, carefully implemented to reduce overhead as much as possible, making viable to have thousands of actors flying around
    with minimum performance impact while not falling to the quirks and weirdness of instanced meshes.
    This is specially useful for VR and Mobile platforms!

    Yes, the best part of an Object-Pool is that your actors will still be actors with physics simulation, unique materials and all that; but still,
    your game will render much much faster when you're in need of rendering and animate thousands of unique projectiles, for example.


    Let me show a practical example video; This is exactly the same simulation running in two different maps...
    First one using normal Spawn/Destroy logic for bullets, it's a "bullet hell" game; then doing the same, but using pooling system:



    As you can see in the video, there's 1.000 bullets running around, every second ~220 of them are destroyed and more 200s are created.
    For just 200 bullets being spawned/destroyed every second, my average fps on UE4 rapidly falls to around 27fps.

    * NOTE: This is profiling taken on a GTX 780, running in 4K resolution; when in 1080p results are even better.
    * NOTE: My machine can't go over 75fps with UE4 in 4K resolution, even when Playing In Editor empty scenes.






    But then on the second map, with pooling system running, my average fps for the same 1.000 bullets being shot is now around 71fps.
    So those 1.000 bullets are now close to insignificant to my FPS, since I can't go over 75fps anyways.
    I'm not great with maths, but I believe that this is something more than 250% improvement for the same game:











    Okay, but for a programmer an object pool is relatively simple to make. What is the point here?
    Well, I've gotta buy assets from Marketplace too you know You help me help you!
    Also, if you completely hate C++ this is code you don't have to touch, I'll keep it updated for you.
    Btw, this will always run way much faster than any pooling made by Blueprints, it runs entirely in C++ behind the scenes.
    I can tell because none of my Blueprint prototypes did run that fast; they've added more overhead instead.
    So, if your game is projectile intensive, you don't know C++, you don't want to hire a programmer; then this is for you

    Let's have a pool party!


    ----------

    [ How-to-Use ]:

    This is very simple to implement into any UE4 project, install the plugin from the launcher then follow these small steps:


    * From your Asset Browser panel, right click and select "Synaptech -> Object Pool" to create a new Pool component.
    You can attach this new component to whatever Actor you want in your level, this component is our memory pool:




    * Now, you need to create a new Pooled Actor class OR re-parent the base class of the AActor you need to be pooled;
    If your Actor is child of multiple classes, just re-parent it's uppermost outer (example: AActor -> Projectile -> MG_Bullet -> M8_Bullet; just re-parent Projectile as a child of APooledActor instead of AActor):



    * Now all your Actor Blueprint can be used by your Object Pool component as part of its pool; You can use multiple Object Pool components in your level at same time and you can attach it to any 'manager' Actor;
    Or if you which so just create an Empty Actor to hold your new Object Pool then add your newly created component to it:



    * After adding the Pool Component to the Empty Actor, on the "Object Pool" property category, set any of your Blueprints to the Pool and how many instances you need to be pre-loaded into memory before game starts;
    Set the Template Class which is a child of APooledActor (example: from case above, could be any of the Projectile, MG_Bullet or M8_Bullet classes).
    Then set Pool Size, how many copies of your pooled Actor class your design implies are needed for your game to run this level in particular:



    * Everything set; now we simply have to use our pooled Actor when needed. Now, instead placing copies of the actor manually into the level or using "Spawn Actor from Class" Node...
    To retrieve an Actor from the Pool, we get a reference to the Pool component that has generated the pooling for the class of our interest and call Spawn Actor from Pool from anywhere we wish:
    (Spawning from the Pool will fail if all available instances are currently spawned and being used in the level)


    * From there, your pooled Actor is a regular Actor just like any other and can code it to do anything you need. Now, when you need the pooled Actor removed from the Level, do not destroy it!
    Instead, send it back to the Pool where it stays sleeping while your Pool component is still present in the level (note: if you destroy the Actor owner of the Pool component, all its pooled Actors will be destroyed with it as well).
    All your Actors child of APooledActor have this default Node which you can use to remove them from the level without causing hiccups in the game.


    * And finally, APooledActors can emulate BeginPlay() and EndPlay() behaviour every time they come in and out from the Object Pool component;
    To do that, you can execute functions attached to Events they have specially setup for this, Event On Pool Begin Play and Event On Pool End Play:



    ----------

    And that's all, hope you make good use of this
    Depending on use case and demand, I will soon update to add support for Pooled Characters and Pawns!
    Just like with my other plugins, my intentions here are to gather funding to buy myself assets from Marketplace too, so I plan to make it very affordable for everyone, $10 bucks or something like that; cheers!

    --------------------

    [1.2.0]:: New API Functions:

    C++ coders can use templated functions to cast directly, Blueprints have to cast manually.


    (Object Pool Component):

    * GetObjectArray(): Directly access Actors storage, be careful what you do with this.
    * GetObjectsFromPool(): Returns two Arrays from the Pool, Spawned and Inactive member Actors.
    * GetSpawnedObjects(): Returns an Array of currently spawned Actors from the Pool.
    * GetInactiveObjects(): Returns an Array of currently inactive Actors in the Pool.
    * GetSpawnedObject(): Returns an Actor currently spawned from the Pool.
    * GetInactiveObject(): Returns an Actor currently inactive in the Pool.

    Templated C++ Functions:

    * GetObjectsFromPool<T>(): Returns Array of Actors from Pool, type-casting to T.
    * GetSpawnedObjects<T>(): Returns Array of spawned Actors from Pool, type-casting to T.
    * GetInactiveObjects<T>(): Returns Array of inactive Actors in the Pool, type-casting to T.


    (Pawn Pool Component):

    * GetPawnArray(): Directly access Pawns storage, be careful what you do with this.
    * GetPawnsFromPool(): Returns two Arrays from the Pool, Spawned and Inactive member Pawns.
    * GetSpawnedPawns(): Returns an Array of currently spawned Pawns from the Pool.
    * GetInactivePawns(): Returns an Array of currently inactive Pawns in the Pool.
    * GetSpawnedPawn(): Returns a Pawn currently spawned from the Pool.
    * GetInactivePawn(): Returns a Pawn currently inactive in the Pool.

    Templated C++ Functions:

    * GetPawnsFromPool<T>(): Returns Array of Pawns from Pool, type-casting to T.
    * GetSpawnedPawns<T>(): Returns Array of spawned Pawns from Pool, type-casting to T.
    * GetInactivePawns<T>(): Returns Array of inactive Pawns in the Pool, type-casting to T.


    (Character Pool Component):

    * GetCharacterArray(): Directly access Characters storage, be careful what you do with this.
    * GetCharactersFromPool(): Returns two Arrays from the Pool, Spawned and Inactive Characters.
    * GetSpawnedCharacters(): Returns an Array of currently spawned Characters from the Pool.
    * GetInactiveCharacters(): Returns an Array of currently inactive Characters in the Pool.
    * GetSpawnedCharacter(): Returns a Character currently spawned from the Pool.
    * GetInactiveCharacter(): Returns a Character currently inactive in the Pool.

    Templated C++ Functions:

    * GetCharactersFromPool<T>(): Returns Array of Characters from Pool, type-casting to T.
    * GetSpawnedCharacters<T>(): Returns Array of spawned Characters from Pool, type-casting to T.
    * GetInactiveCharacters<T>(): Returns Array of inactive Characters in the Pool, type-casting to T.


    (Pooled Actor, Pawn, Character Classes):

    * GetOwningPool(): Returns a direct reference to the Pool Component owner of this Actor.
    Last edited by BrUnO XaVIeR; 10-01-2017, 01:20 PM.
    | Finite State Machine | Auto-Save Plugin | USQLite Plugin | Object-Pool Plugin | Sound-Occlusion Plugin | Anti-Cheat Plugin | Property Transfer Tool |

    #2
    ok, i don't know C++, I'll wait for your plugin

    Comment


      #3
      This is actually very useful for a lot of things, definitely worth $10 I'd say.

      Hope it gets put on the marketplace ASAP!

      Good job
      Why do all programmers wear glasses? Because they can't C#

      Comment


        #4
        I have just updated original post, with Marketplace release date, and the tutorial on how to use the plugin
        | Finite State Machine | Auto-Save Plugin | USQLite Plugin | Object-Pool Plugin | Sound-Occlusion Plugin | Anti-Cheat Plugin | Property Transfer Tool |

        Comment


          #5
          Awww, I really like "quality of life" plugins like this. Could you please update us when it's ready to be thrown money at?
          Youtube Channel

          Comment


            #6
            Originally posted by BoredEngineer View Post
            Awww, I really like "quality of life" plugins like this. Could you please update us when it's ready to be thrown money at?
            [MENTION=12960]BoredEngineer[/MENTION]
            Marketplace released this today:

            https://www.unrealengine.com/marketp...ct-pool-plugin
            | Finite State Machine | Auto-Save Plugin | USQLite Plugin | Object-Pool Plugin | Sound-Occlusion Plugin | Anti-Cheat Plugin | Property Transfer Tool |

            Comment


              #7
              Thank you!
              Youtube Channel

              Comment


                #8
                Essential plugin but having crash-issue with 4.14. Seems like if the pool have some destroed actors, then the editor crashes when "empty object pool"-node is used, the related blueprint (that have the pool) is destroyed or play in viewport session is ended.

                Comment


                  #9
                  Originally posted by SaOk View Post
                  Essential plugin but having crash-issue with 4.14. Seems like if the pool have some destroed actors, then the editor crashes when "empty object pool"-node is used, the related blueprint (that have the pool) is destroyed or play in viewport session is ended.
                  Thanks, I will check this right now.
                  Just keep in mind that pooled objects are not supposed to be destroyed (destroy the pool owner instead), but it shouldn't crash because of that, I will see where the mistake is.


                  Edit:

                  [MENTION=50574]SaOk[/MENTION]

                  Thank you for finding this issue;
                  I have found the crash reason, I've fixed it and will submit to Epic as soon as I can.

                  The thing is, I forgot about one thing: to check if any of Pooled Actors are marked by the engine as Pending Kill before I tell the Pool Component to be empty.
                  The result is that once you destroy a pooled actor, it is not immediately gone... It is marked as pending kill until GC is able to collect, but there's a pointer in the Pool holding reference to the destroyed Actor and once you use the 'Empty Pool' in this case you are actually calling Destroy() function 3x on an Actor that is not valid anymore.
                  I just had to check if the pooled Actors are valid at low level, just one line of code inside the Empty Pool function.
                  | Finite State Machine | Auto-Save Plugin | USQLite Plugin | Object-Pool Plugin | Sound-Occlusion Plugin | Anti-Cheat Plugin | Property Transfer Tool |

                  Comment


                    #10
                    Great to hear , thanks for the instant response. Cant wait to try the upcoming update.

                    Was using the pool for bullets. Tried to prevent those getting destroyed, but seems those ended up to z world removal.

                    Comment


                      #11
                      I've sent the files to Epic already; I have to sit and wait now.


                      Edit:

                      Fix is already on Marketplace.
                      Last edited by BrUnO XaVIeR; 02-10-2017, 07:21 PM.
                      | Finite State Machine | Auto-Save Plugin | USQLite Plugin | Object-Pool Plugin | Sound-Occlusion Plugin | Anti-Cheat Plugin | Property Transfer Tool |

                      Comment


                        #12
                        Does this plugin support c++ Actor ? And how to pool the particles?
                        Last edited by liuwei; 02-12-2017, 11:48 PM.

                        Comment


                          #13
                          Hi Bruno! Great plugin!

                          Quick question: To get an actor spawned from the pool to tick i have to enable ticks in the On Pool Begin Play? It was the only way i could get ticks to work. (and probably a stupid follow up question; should i then disable ticks before returning it to the pool? )

                          Comment


                            #14
                            I'll definitely be buying this!! Very excited for the Pooled Characters and pawns!

                            Comment


                              #15
                              Originally posted by gotgrassct View Post
                              I'll definitely be buying this!! Very excited for the Pooled Characters and pawns!
                              Thanks, Character support will come soon; I just hsve to deliver paid work first :s
                              | Finite State Machine | Auto-Save Plugin | USQLite Plugin | Object-Pool Plugin | Sound-Occlusion Plugin | Anti-Cheat Plugin | Property Transfer Tool |

                              Comment

                              Working...
                              X