[Plugin] Object Pool Component

Any idea what causes the first few projectiles spawned to stop at a certain distance and fall to the ground? (the rest shoot normally tho every once in a while another projectile will stop and fall to the ground). Also, why does exposing a variable on spawn and setting the max speed of the projectile (using that variable) not work in the construction script? This works flawlessly for epics projectile component…

I’d suggest downloading demo project and see how physics collision channels are setup there.

And “Construction Script” will not run if you have “Reconstruct” option disabled.


Btw, executing Construction Script is very expensive function call. If you really need it to run every time, pooling will give your game little performance gain over simply using a normal spawned projectile.

@amartis111

Version 1.6.0 is up on Marketplace and this version should now contain binaries for Mac Editor, and Mac + IOS runtime binaries as well.
Please let me know if that works for you, I report back to EpicGames.

Hey ,

Updated 4.20 and IOS packaging is now working on 4.20.2. 4.19.2 still crashes, but, no worries:)

Thanks for your help
Cheers

Ah, I didn’t realize calling the construction script would be expensive… I’ll avoid that. I’ll look into the demo. I still have not been able to replicate the spawned bullets down to the client from a dedicated server. Setting it up just like the normal projectile doesn’t work. Hopefully ill be able to use it for spawning pawns on the server otherwise I won’t be able to use this plugin at all :confused:

Yes, I sent update request for Unreal 4.20 only; no earlier versions.

I will add to my todo list built-in replication support for this plugin, but I’ve been very busy these last months so I can’t say when this will be done.

[USER=“434”] XaVIeR[/USER] I need some help with proper implementation

We have a near limitless amount of players in our multiplayer game and likewise for the world size (we have solutions for these limitations in UE, don’t mind it)

There are many different weapons and these weapons can have many different attachments that fire many different projectiles; the projectile class stems from APooledActor.

So lets say you have an assault rifle, it’s primary fire has fire either AKineticAmmoProjectile or AEnergyAmmoProjectile, and it’s attachment is an underbarrel launcher that can fire AFragGrenadeProjectile or APulseGrenadeProjectile. The weapon and attachments can change the ammo they’re firing (similar to reloading, there’s a delay then the new ammo goes in), and naturally the character can switch weapons and the attachments on the weapon.

So where the actual pools are concerned, presumably there would be a pool for AKineticAmmoProjectile, a pool for AEnergyAmmoProjectile, and same for the grenades? How would I handle instantiation and switching pools and all that stuff when changing weapons and attachments? Particularly needs to happen without it hitching.

Cheers

I would create different auto-initialized Pool Component for each class and attach them to player, not to weapons.

Then on spawn from pool, set projectile transform to align with current weapon… Whenever weapon is switched, it’s bullets are already in memory so nothing would instantiate until a new persistent level is loaded or player destroyed.

Thanks. So just to be clear, if I had 500 different projectile types, each player would have 500 pools? Is that possibly an issue?

Yes that would scale badly.
I would develop projectile sub-classes in case like that, i.e:

APooledActor -> AProjectile…

Then code the AProjectile Blueprint to “change behavior” depending on weapon equipped, to avoid doing that.

Making that many pools would be horrible.
I would just go without pooling then, too many allocations.

Hmm there’s still one issue with that. If the projectile is an actor with components for collisions, but those components have various components for visuals and audio fx that are specific to each projectile I’d still end up having to spawn those, right?

I guess I could add some components in advance and simply not use them for some? Will there be overhead with changing the particles on each spawn?

I will investigate if it’s possible to “multicast” a Pool Component; that would be ideal…
I have NO idea if that would be possible, but if there’s a way to do that you could then have all projectiles pooled from the same memory pool component.

I’ll work on a solution that works with the current system, meanwhile I’ll cross my fingers but not hold my breath for your solution :slight_smile:

ExposeOnSpawn + SpawnActorFromPool node still reads default value in C++

Expose on Spawn only work based on the custom Spawn from Pool nodes.

It’s the Node whose does all the expose setting, if you call Component functions in C++ all that process is skipped (no Kismet Compiler involved).

Makes sense, thanks for clarifying

Edit: Actually makes a lot of sense, it’s the same for the default UE4 spawn actor nodes too, which is why you use deferred (and you have deferred from pool nodes, so that works fine)

Edit again: Nope doesn’t work, OnPoolBeginPlay is being called after BeginDeferredSpawnFromPool and not after FinishDeferredSpawnFromPool - I believe this is an actual bug?

Let me provide an example. This code is responsible for firing the projectile. It spawns the projectile deferred (BeginDeferredSpawnFromPool), then it sets the settings for that specific projectile (OffsetTemp for this example), then it completes the spawn (FinishDeferredSpawnFromPool). The issue is that OnPoolBeginPlay is called before FinishDeferredSpawnFromPool is called which defeats the purpose of deferring the spawn.


AVWPProjectile* UVWProjectileComponent::FirePooledProjectile(const FVector& OffsetTemp)
{
    if (!InstigatorActor || !Handler)
    {
        // Died during firing sequence?
        return nullptr;
    }

    const FVector SpawnLocation = GetFireLocation();
    const FRotator SpawnRotation = GetFireRotation();

    AVWPProjectile* NewProjectile = nullptr;

    bool bSucceeded = false;
    APooledActor* PooledProjectile = UObjectPool::BeginDeferredSpawnFromPool(this, Pool, FPoolSpawnOptions(), FTransform(SpawnRotation, SpawnLocation), ESpawnActorCollisionHandlingMethod::AlwaysSpawn, InstigatorActor, false, bSucceeded);

    if (bSucceeded && PooledProjectile)
    {
        NewProjectile = Cast<AVWPProjectile>(PooledProjectile);

        NewProjectile->PooledProjectile->OffsetTemp = OffsetTemp;  // Already OnPoolBeginPlay has been called, it's too late to set defaults

        UObjectPool::FinishDeferredSpawnFromPool(PooledProjectile, FTransform(SpawnRotation, SpawnLocation));
    }

    return NewProjectile;
}

I will note this and step through code tomorrow morning.

I did a temporary fix in the meantime. I moved SpawnFromPool out of BeginDeferredSpawnFromPool into FinishDeferredSpawnFromPool. I also had to expand FinishDeferredSpawnFromPool with the options required for SpawnFromPool.