Is it possible for niagara particle collisions to apply a gameplay effect to the collider target? I’m making a bullethell game and trying to see if I can use niagara for firing projectiles instead of spawning actors, but can’t seam to figure out how to apply damage to a target via gameplay effect from a niagara collision. Is this even possible? or would it be better to just use Object Pooling with actors?
Niagara should not be used to drive gameplay logic. You will run into problems when your simulation drops results because of visibility culling, scalability culling, readback delay, etc. Also, Niagara simulations are not replicated on the network and don’t run on server instances, so multiplayer would be impossible that way.
There are better ways to implement a bullet hell game than to use Niagara. You should try and learn C++ to implement the core bullet management and then maybe map particles to them.
If you’re using cpu collisions, Niagara is doing two line traces per particle. This is really bad for perf and makes your game unplayable on slow hardware. It also has a frame delay and doesn’t take into account the movement of objects in the scene, it assumes everything but the particles is standing still.
If you implement the game logic yourself, don’t use line traces for your collisions, but implement a custom solver instead.
I don’t need multiplayer. This is entirely single player. I also don’t need them to do anything if culled. They’ll follow the player and only damage what’s on screen. I even have a kill volume setup to destroy projectiles if they go too far off screen.
I managed to implement this entirely using Niagara and BP. The Niagara system is attached to the player and listening for collision events from Niagara inside of a GameplayAbility.
Are there any tutorials for this better way? I’ve been looking into this for weeks trying to put together solutions to try. My original implementation of spawning instanced static meshes was terrible performance. Are you meaning that I should implement object pooling? I tried and it still chokes after too many projectiles.
I want to do this entirely from BP. I spend all day in code as my day job. This is a break from staring at lines of code.
Can you define slow hardware? I’m not looking to make this work on PCs from 15 years ago. Works fine on my 5700XT with thousands of projectiles.
So they won’t be able to hit an AI slowly moving directly towards the player with no other movement? I don’t need precision aiming or anything.
Custom resolver for Niagara or for the C++ solution you mentioned?
Below is what I’ve managed with Niagara. They all have collision and report back their hits to my gameplay ability fine.
Checked my CPU usage and I’m only seeing 10-15% usage with 10,000 projectiles (my game is unlikely to have this many, but still for arguments sake) on a AMD Ryzen 9 3900X 12-Core Processor in the editor. I imagine even on older hardware it’d still be fine. Do you still think this will be a major concern? In reality there will probably only be 1,000 projectiles and 200ish actors in scene.
Niagara lets me easily have the shot patterns I want as well, which was a pain calculating that movement for static mesh projectiles. I really don’t want to have to go back to object based as I like the results of this much better.
I think I see what you might mean. It collided with my moving pillars but the collision data outputs a collision position of the box in the far distance behind it. So is object pooling my only option here?
You can of course still use Niagara to display the sprites or meshes. But I would handle the particle movement and collision in C++ or Blueprint. Have an array of all your bullets, iterate over them once per tick and resolve any collisions or movement updates, then send the data to Niagara for rendering.
To send the data you can either use the array data interface if you want to stay with Blueprints or write a custom data interface so each particle can query the data on its own. There is a plugin called “ExampleCustomDataInterface” that contains a sample data interface you can copy and paste, but it’s all C++ at that level.
So I’d still need an actor per bullet right? Since I need individual bullet collision and movement. What I had before was the below structure.
- Actor
-
- Collider
-
-
- Niagara System
-
Could I put all of these inside of another Actor, turn off their ticks, and have that root actor move the bullets in its tick? Then it’d be 1 tick for possibly hundreds of bullets, but would still need some kind of object pooling I think. I guess kind of like swarm AIs and such.
I’m not sure what you mean by send the data to Niagara. So I could avoid attaching a Niagara system or emitter per bullet and instead have 1 and it just gets told the location, velocity, etc… of those bullets to render?
I got the collision target working with Niagara. I was using the wrong BP to detect the collided actor, lol. I’m now using Sphere Overlap Actors, which is working fine with moving actors. I was trying to do a sphere trace last time, whoops.
Do you think this would still be a bad idea to do? Will try object pooling and look into this further as well. Be great if there were some tutorials on large spawns like this or even better a built in way of dealing with it more simply.
No, individual actors or even components per bullet would be far too expensive! Don’t rely on the engine’s collision feature for a bullet hell game, instead have a list of all objects and actors the bullets can collide with, then check for collisions yourself. If you don’t want to implement your own solver you can always do traces or sweeps using the physics system.
The new mass framework in UE5 might also be a good fit for this, as it’s meant to update thousand of entities per tick. You can check it out here: Large Numbers of Entities with Mass in Unreal Engine 5 | Talks and demos
I’ve no idea where to even begin to doing that. Is there any tutorials available? I’m not expecting thousands of projectiles on screen. Probably anywhere from 200-300 realistically.
I’d love to, but the documentation for Mass is basically non-existing. It’s still marked experimental and doesn’t seam viable for anything other than AI crowds right now.
Ok, I’m working on a bullet manager. It’s still working with actors, because I don’t know how to do what you’re suggesting, but they don’t have a projectile movement component and I’m working on moving their movement to the manager (e.g. 1 manager controls the movement of all of its bullets in its tick) so that they don’t tick. They won’t have physics either. I think that’s the best I can do for now.
Got the bullet manager working so it’s managing the movement of the actor bullets. Result is a single tick for 100 bullets. Seams to be doing well. I’m still using actor components and collisions though. I’m not sure how to replace those. Using Niagara still seams to perform better.
@Michael.Galetzka I think I figured out the data driven approach! I’m going to give it a shot tomorrow and through the weekend. It finally just clicked, lol.
I’m going to try keeping track of the projeciles transforms in an array in my bullet manager when they’re supposed to be spawned then in my bullet managers tick I can loop them, “move” them, and run a collision trace to see if there’s a hit. Combined what I learned getting Niagara collisions working and now the object pooled projectiles working to reach this point.
Only thing I don’t know how to do is feed their transforms into Niagara so I can have a particle effect render where the projectile would supposedly be. Are there any tutorials or hints on how to do this?
Thank you for all the tips! Was of HUGE help.