Overview
PoolPro is a world subsystem for Unreal Engine 4.27 and 5.8 that keeps objects you use again and again — projectiles, effects, pickups, enemies, list entries — in pools. Taking an object activates a free pooled one when available; otherwise new objects are spawned over the following frames. Returning an object deactivates it and keeps it for the next request.
- Works with any
UObject, Actor or User Widget class without changes to the class.
- One pool per class, created on first use, one set of pools per world.
- Spawning spread over frames (Spawn Objects Per Frame) with four priorities.
- Inactive actors are hidden, have collision and ticking disabled and are moved out of the way; inactive widgets are collapsed.
- Handles identify objects that are still being spawned and can cancel queued requests.
- Callback interface for pooled objects and factories for custom object types.
Requirements
| Requirement | Details |
| Unreal Engine | 4.27 and 5.8 (verified clean on both) |
| Modules | PoolPro (Runtime), PoolProEditor (UncookedOnly — the Blueprint nodes, not packaged into games) |
| Dependencies | None (engine modules only; no other plugins are enabled) |
| Language | Blueprints and C++ |
| Platforms | Win64 and Mac (both modules list these platforms in the plugin descriptor). The code is platform-independent engine C++ with no OS-specific calls. |
Installation
- Install PoolPro from Fab into your engine, or copy the
PoolPro folder into your project's Plugins folder.
- For a C++ project, regenerate project files and build the editor target.
- Open the project, enable PoolPro in Edit > Plugins and restart the editor.
- C++ only: add
PublicDependencyModuleNames.Add("PoolPro"); to your Build.cs.
Verifying the installProject Settings > Plugins > PoolPro exists, and searching for Take From Pool in an Event Graph shows the node under the PoolPro category.
Quick start
Blueprint
- In an Event Graph, add Get Pool Pro.
- Add Take From Pool, connect Get Pool Pro to its Target pin, choose the Object Class, a Transform and a Priority.
- Use the Object output after Completed fires — immediately when a free object was in the pool, otherwise once the new object has been spawned.
- When the object is no longer needed, call Return To Pool (on an actor, the Object pin defaults to self).
- For many objects at once use Take From Pool Array and Return To Pool Array.
C++
// Build.cs: PublicDependencyModuleNames.Add("PoolPro");
#include "PoolProSubsystem.h"
// AMyWeapon has: FPoolObjectHandle LastShot;
void AMyWeapon::Fire()
{
UPoolProSubsystem* Pool = UPoolProSubsystem::GetPoolPro(this);
if (!Pool)
{
return;
}
LastShot = Pool->TakeFromPool<AMyProjectile>(GetActorTransform(), [](const FPoolObjectData& Data)
{
Data.GetChecked<AMyProjectile>().Launch(); // runs now, or when the object has been spawned
});
}
void AMyWeapon::CancelShot()
{
if (UPoolProSubsystem* Pool = UPoolProSubsystem::GetPoolPro(this))
{
Pool->ReturnToPool(LastShot); // also cancels the request if it is still queued
}
}
Other C++ entry points: TakeFromPoolArray, TakeFromPoolOrNull, TakeFromPoolArrayOrNull, ReturnToPoolArray, CreateNewObjectsArrayInPool and EmptyAllByPredicate. Subclass UPoolProSubsystem to customise behaviour and fetch it with UPoolProSubsystem::Get<UMyPoolSubsystem>().
Taking & returning
| Node | Type | Description |
| Get Pool Pro | Pure | Returns the UPoolProSubsystem of the world (from the world context; without one, the current play world, or the editor world in the editor). |
| Get Pool Pro By Class | Pure | Same for a subclass of the subsystem; the output pin takes the chosen class. |
| Take From Pool | Callable | Pins: Target, Object Class, Transform, Priority. Completed fires with Object when the object is ready. Event Graphs and macros only. |
| Take From Pool Array | Callable | Pins: Target, Object Class, Amount, Priority. Completed fires with Objects once all are ready. |
| Return To Pool | Callable | Deactivates an object that belongs to a pool (taken from it or registered) and keeps it for reuse. Returns true on success. |
| Return To Pool Array | Callable | Returns several objects; true when all succeeded. |
| Make Spawn Request | Pure | Builds a FSpawnRequest (class, transform, priority) with a fresh handle. |
| Create New Object In Pool | Callable | Always spawns a new object for a spawn request and registers it; returns its handle. |
| Register Object In Pool | Callable | Adds an existing object (as FPoolObjectData) to its class pool. |
Priorities
| Node | Type | Description |
| Normal | Enum value | Added to the end of the spawn queue. |
| Medium | Enum value | Inserted after High requests and before Normal ones. |
| High | Enum value | Inserted at the front of the queue for the next frame. |
| Critical | Enum value | Spawned synchronously in the same call; avoid for large batches. |
Pool queries & management
| Node | Type | Description |
| Get Pool Object State | Pure | None (not pooled), Inactive (free) or Active (taken). |
| Contains Object In Pool | Pure | True when the object is handled by a pool. |
| Contains Class In Pool | Pure | True when a pool exists for the class. |
| Is Active | Pure | True when the object was taken from its pool. |
| Is Free Object In Pool | Pure | True when the object is pooled and free. |
| Is Registered | Pure | True when the object is known to a pool. |
| Get Free Objects Num | Pure | Number of free objects in the pool of a class. |
| Get Registered Objects Num | Pure | Number of objects in the pool of a class. |
| Is Pool Object Valid | Pure | True when pool object data holds a valid object and handle. |
| Find Pool Object By Handle | Pure | Pool object data for a handle (empty while the object is still queued). |
| Find Pool Handle By Object | Pure | Handle of a pooled object. |
| Find Pool Objects By Handles | Pure | Pool object data for every handle whose object exists. |
| Empty Pool | Callable | Destroys every object in the pool of a class and removes the pool. |
| Empty All Pools | Callable | Destroys the objects of every pool. |
| Add Factory | Callable | Registers a factory class for the object class it handles. |
| Remove Factory | Callable | Removes a factory. |
| Find Pool Factory Checked | Pure | Factory used for a class (closest registered factory up the class hierarchy). |
| Get Object Class By Factory | Pure | Object class handled by a factory class. |
Object callbacks
Implement the UPoolObjectCallback interface (Pool Object Callback) on a pooled class to be notified.
| Node | Type | Description |
| On Take From Pool | Event | Called when the object is taken; the payload (FTakeFromPoolPayload) carries the Transform and whether the object was newly spawned (Is New Spawned). |
| On Return To Pool | Event | Called when the object is returned. |
| On Changed State In Pool | Event | Called with the new EPoolObjectState when the object is activated or deactivated. |
Pool factories
A factory defines how objects of a class family are spawned, activated, deactivated and destroyed. The pool for a class uses the closest factory up its class hierarchy. Default factories: UPoolFactory_UObject (any object, created with NewObject), UPoolFactory_Actor (spawned on the persistent level with deferred construction; inactive actors are hidden, have collision and ticking disabled and are moved far away) and UPoolFactory_UserWidget (created with Create Widget; inactive widgets are collapsed). Derive from UPoolFactory_UObject in Blueprint or C++ and add the factory in the settings or with Add Factory.
| Node | Type | Description |
| Get Object Class | Pure | Overridable: the base class this factory handles. |
| Request Spawn | Callable | Overridable: queues a spawn request by priority (Critical is processed at once). |
| Spawn Now | Callable | Overridable: creates the object for a request. |
| Process Request Now | Callable | Spawns a request immediately and runs its callbacks. |
| Dequeue Spawn Request | Callable | Removes and returns the first queued request. |
| Dequeue Spawn Request By Handle | Callable | Removes and returns the queued request with a handle. |
| Is Spawn Queue Empty | Pure | True when nothing is waiting to be spawned. |
| On Pre Registered | Callable | Runs before a new object is registered in its pool. |
| On Post Spawned | Callable | Runs after a new object is spawned and registered. |
| On Next Tick Process Spawn | Callable | Overridable (protected): spawns the next batch of queued requests each frame. |
| Destroy | Callable | Overridable: destroys an object when its pool is emptied. |
| On Take From Pool | Callable | Overridable: prepares an object when it is taken (the actor factory applies the transform). |
| On Return To Pool | Callable | Overridable: prepares an object when it is returned. |
| On Changed State In Pool | Callable | Overridable: activates or deactivates an object. |
Types
| Node | Type | Description |
| UPoolProSubsystem | Class | World subsystem that owns the pools and factories (Blueprintable). |
| FSpawnRequest | Class | Spawn request structure: Transform, Priority, read-only Handle. |
| FPoolObjectData | Class | Pooled object structure: Pool Object, Handle, and whether it is active. |
| FPoolObjectHandle | Class | Identifies a pooled object, including one that is still queued for spawning. |
| FTakeFromPoolPayload | Class | Payload of On Take From Pool. |
| EPoolObjectState | Class | None, Inactive, Active. |
| ESpawnRequestPriority | Class | Normal, Medium, High, Critical. |
Settings
Project Settings > Plugins > PoolPro (saved to DefaultPoolPro.ini). Read them at runtime with Get Pool Pro Settings, Get Spawn Objects Per Frame and Get Pool Factories.
| Setting | Default | Description |
| Spawn Objects Per Frame | 5 | How many queued objects each factory spawns per frame. |
| Pool Factories | PoolFactory_UObject, PoolFactory_Actor, PoolFactory_UserWidget | Factories created for every PoolPro subsystem. |
Troubleshooting
| Symptom | Cause and fix |
| Take From Pool is missing in a function graph | The node completes asynchronously and is available only in Event Graphs and macros. |
| Blueprint compile error on the Target pin | Connect Get Pool Pro to the Target pin of Take From Pool / Take From Pool Array. |
| Ensure "Can not find PoolPro for ... class in ... world" | Get Pool Pro found no world. Pass a world context (any actor or component) when calling it from objects that are not in a world. |
| Objects appear a few frames after the request | New objects are spawned from a queue, Spawn Objects Per Frame per frame. Raise the setting, use a higher priority, or fill the pool ahead of time (take and return objects during loading). |
| Returned actors are far away from the level | The actor factory moves inactive actors far away (in addition to hiding them) so that clients do not collide with them; they get the requested transform when taken again. |
| A pooled widget is not on screen after Take From Pool | The widget factory only creates and shows widgets; add the widget to the viewport or to a panel yourself. |
| Pools are emptied while working in the editor | Pools of the editor world are emptied when that world is destroyed (for example when another map is opened), to avoid keeping objects alive. |
| Assertion "'FoundFactory' is null" when taking an object | No factory handles the class. Keep PoolFactory_UObject in Pool Factories, or add a factory for that class. |