Object Pooling
Spawning and destroying UObjects and AActors in Unreal can be expensive so for objects that are spawned often (such as projectiles) it can be much cheaper to reuse a previously created object. The Object Pool Subsystem has been created to simplify this process by provisioning available actors based on a set of requirements which are gathered from other assets in the level. If the actor has not yet been spawned into the pool, a new one will be spawned and added to to the pool.
Note
The system currently only supports non-replicated objects.
Inheriting from IGSPoolableObject
Before an object can be pooled it must inherit from IGSPoolableObject. This interface provides a few functions that are called when the pooled object is used:
OnSpawned
- Called when the object is initially spawned. A unique handle is provided which must be stored by the object and used to release the object again later.OnActivated
- Called when the object has been provisioned via the Object Pool Subsystem.OnDeactivated
- Called when the object has been placed back into the pool.
At the end of an objects lifetime, instead of called Destroy on the object UGSObjectPoolSubsystem::ReturnPooledObject must be called to return the object back into the pool. The handle for this function is provided by the interfaces OnSpawned function.
Setting Up Requirements
To add requirements for a pooled object, call AddObjectRequirements on the GSObjectPoolSubsystem with the desired class and amount of objects required in the pool. Typically this would be done during a loading screen to hide any potential loading hitches but it can also be called during the middle of a game if necessary. A GSPoolingRequirementHandle is returned which can later be used to remove the requirements from the list via RemoveObjectRequirements.
Pooling via Weapons and Attachments
To simplify this process even further, weapon and attachment dependencies can be requested via the GSWeaponsSubsystem. Create a new Data Table with a row type of GSPreloadDataRow and then define each weapon data and attachment type that can be used during this level. PreloadObjects can then be called which will handle the loading of all of the soft references in the list and also gather all pool requirements via the Emitter and WeaponAttachmentExecutions GatherPoolingRequirements functions.
Once these data assets have been loaded, they are stored in a map and can be recalled with GetLoadedWeaponData and GetLoadedAttachmentClass via their Unique ID which is assigned in the asset. Whenever using these functions, ensure the load has finished by using CallOrRegisterPreloadComplete or OnPreloadComplete.
Using Pooled Objects
To request a pooled object call UGSObjectPoolSubsystem::RequestPooledObject. Ensure that the preload has finished by binding to OnPreloadComplete or passing in a delegate which will be called once the preload has completed.
Debugging
Gunsmith.Pooling.PrintRequirements
- Prints out all data related to the object pool. This can be used to easily work out if the correct amount of objects have been spawned for your loadout.