Ninja Bear Studio Plugins Help

Actor Pooling

It is common for combat systems to require frequent spawning and destroying of actors, such as projectiles or cast actors, in short intervals.

To mitigate the performance cost of constant actor spawning and destruction during gameplay, an Actor Pool was introduced to the Combat System. This pool prepares a predefined number of instances of frequently used actors for each combatant.

The Actor Pool Component

Each combatant has its own Actor Pool, represented by the NinjaCombatActorPoolComponent. You can configure all the actors that will be pooled and specify how many instances will be available.

Combatants using an Actor Pool must implement the CombatPoolProviderInterface to provide the component, allowing external functionalities, such as the Projectile Request, to quickly retrieve and use the pool.

Add the Actor Pool component to your character.

Actor Pool Component

Add the Provider Interface and return the component, from the appropriate function.

Actor Pool Provider
#pragma once #include "CoreMinimal.h" #include "GameFramework/Character.h" #include "Interfaces/CombatPoolProviderInterface.h" #include "PluginLabsCharacter.generated.h" class UNinjaCombatActorPoolComponent; UCLASS() class PLUGINLABS_API APluginLabsCharacter : public ACharacter, public ICombatPoolProviderInterface { GENERATED_BODY() public: APluginLabsCharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); // -- Begin Pool Provider interface. virtual UNinjaCombatActorPoolComponent* GetActorPool_Implementation() const override; // -- End Pool Provider interface. private: /** Pool of actors that are frequently used. */ UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = true)) TObjectPtr<UNinjaCombatActorPoolComponent> ActorPool; };

#include "GameFramework/PluginLabsCharacter.h" #include "Components/NinjaCombatActorPoolComponent.h" APluginLabsCharacter::APluginLabsCharacter(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { static const FName ActorPoolName = TEXT("ActorPool"); ActorPool = CreateDefaultSubobject<UNinjaCombatActorPoolComponent>(ActorPoolName); } UNinjaCombatActorPoolComponent* APluginLabsCharacter::GetActorPool_Implementation() const { return ActorPool; }

Poolable Actors

Poolable Actors are primarily defined by the CombatPoolableActorInterface. Any actor implementing this interface can be added to the Actor Pool Component.

It's generally recommended to extend from NinjaCombatPoolableActor, the default base class, rather than directly implementing the interface. This base actor not only implements the Poolable Actor interface but is also configured to support networking and replication, as if the actor was originally placed in the map.

The Actor Pool Component and the base Poolable Actor work together to reduce the initial network overhead that would otherwise occur when replicating many actors being spawned simultaneously to prepare the pool.

The Actor Pool can be configured in the Actor Pool Component by setting the actor class and the number of instances to initialize.

Actor Pool Setup

Actor Lifecycle

When you use Poolable Actors, it is important to keep in mind how the Actor lifecycle changes.

Functions like Begin Play and End Play will be called when the Poolable Actor is created and destroyed by the pool, making them inadequate to handle events that should happen whenever the actor is actually added or removed from the world.

Instead, Poolable Actors use methods defined by CombatPoolableActorInterface:

  • Activate: Invoked when a poolable actor is retrieved from the pool and placed in the world.

  • Deactivate: Invoked when the poolable actor is ready to be returned to the pool.

If you are using the default implementation, NinjaCombatPoolableActor, those methods are already implemented, and you can simply hook any important events to their respective extension points, available to Blueprints and C++.

  • OnActivation: Invoked when the actor is activated on the server and clients.

  • OnDeactivation: Invoked when the actor is deactivated on the server and clients.

Here are some examples of functionalities that should be handled by these events:

  1. Playing a Particle Effect from the start.

  2. Playing a Sound Effect from the start.

  3. Adding velocity to a projectile.

Supported Actors

Currently, the following actors are supported by default by the Actor Pool:

If you need to support new objects, you can do so by extending NinjaCombatPoolableActor, which is recommended, or by implementing CombatPoolableActorInterface.

Retrieving Actors

To retrieve an actor from the pool, you can use the TryGetActorFromPool function, from the Actor Pool Function Library. Supported actors listed before are already retrieved using this functionality and require no additional work.

Actor Pool Retrieval
#include "NinjaCombatActorPoolFunctionLibrary.h" void APluginLabsCharacter::ActivateActor() { AActor* PoolableActor = UNinjaCombatActorPoolFunctionLibrary::TryGetActorFromPool(RequestOwner, DesiredClass); if (IsValid(PoolableActor)) { // The actor was spawned. } else { // The pool does not have an instance available. } }
Last modified: 27 April 2025