rdInst Tutorial 13: Actor Pooling

As of version 1.10, rdInst provides a way to spawn actors very quickly. It uses Actor Pooling – a number of actors are pooled (in a fast way) at the beginning of play and then reused when you’re wanting to spawn them.

The Pool can either add as it goes, or be pre-allocated (fast) on play.


Step 1. Create a Blueprint based on rdActor

This first Blueprint is our Bullet Blueprint. It is simply a cylinder mesh with a glowing material. It has a function in the Tick event to move “forward” until it reaches a distance from it’s origin, then remove itself back to the Actor Pool.

Note that we turn off Tick by default for the actor, the pooling system is in charge of enabling Tick if it’s wanted. In the Blueprint, select the “Class Defaults” from the top toolbar, then in the Details panel, untick the “Start with Tick Enabled” tickbox:

If you’re using components in your pooled actor such as ProjectileMovement components – you’ll also need to disable the “Auto-Activate” to stop them activating when the Pool is being created (Activate them from your Pool events):


Step 2. Create another Blueprint optionally based on rdActor

This Blueprint is our base that fires the bullets, it rotates around at a fixed speed, firing at a fixed interval.

In the BeginPlay event, we simply set how many actors we want in the pool, seeing as our bullets are being driven by tick (just for the tutorial) we also want to make sure “Do Tick” is ticked.

Use the rdInstSubsystem (right-click in the graph and search for “rdinsts”) – that has wrappers for all the BaseActors functions (including rdGetBase) – call the rdPoolActor from there.

Actor Class: The class of actor to pool – this can be any type of actor
Num to Pool: The number of actors to reserve ready to be used from the pool
Premake: When ticked, creates the actors and hides them on BeginPlay
DoTick: When ticked, enables the actors tick when used from the pool
Reuse: When ticked, the oldest item is used when all actors from the pool are used.
Simple Pool: When ticked, doesn’t perform things like disabling/enabling physics when pooling or using.

And the FireBullet Function, which is the part that spawns an actor from the Pool:


Step 3. Done – drag a base blueprint into your level and play.


Step 4. Pool and Depool Events for rdActor objects

If you want to do things such as turn on and off Niagara effects in your Pooled Actors or Components, you can use Custom Pool and Depool Events to execute your own code when the actors are added and removed from the level.

If your Pooled actors are Subclassed from rdActor – you can simply override the Pool and Depool Functions from your actors Blueprint Editor.

Whenever an object is used from the pool or returned to the pool, the appropriate event is called where you can directly initialize and cleanup that instance.


Step 5. Pool and Depool Events for non rdActor objects

If your Pooled actors are not Subclassed from rdActor you can add a “Pool Listener” which is an rdActor in your level.

Just create a new Blueprint subclassed from rdActor and add one to your level.

You assign that as the listener for all your Pooled objects by using the rdSetPoolListener function in its BeginPlay event (you can handle pooling everything from there too so as to keep it centralized).

In your Listener Blueprint, you override those same rdOnActorPooled and rdOnActorDepooled Functions as mentioned in Step 4. The Actor Instance being Pooled/Depooled is passed in as a parameter.

Whenever an object is used from the pool, the rdOnActorPooled event is called, passing in the pooled object instance as a parameter. You can do any initialization on that instance from this event.

Whenever an object is returned to the pool, the rdOnActorDepooled event is called, passing in the pooled object instance as a parameter. You can do any clean-up on that instance from this event.


Step 6. Pool and Depool Events from C++

If you’re wanting the Events from C++, you can simply derive the Pool/Depool methods:

void AMyrdActor::rdOnActorPooled_Implementation(AActor* actor) {

	UE_LOG(LogTemp,Display,TEXT("rdOnActorPooled"));
}

void AMyrdActor::rdOnActorDepooled_Implementation(AActor* actor) {

	UE_LOG(LogTemp,Display,TEXT("rdOnActorDepooled"));
}