You are currently viewing Stretchy beam ribbon in Niagara

Stretchy beam ribbon in Niagara

Some time ago I needed to create a system similar to this for a project and I really liked how technically satisfying it was to achieve this effect so I thought to write down a breakdown of the logic for future reference. Please note this is a slightly advanced particle system, I write this assuming the reader is already at least a bit familiarized with Scratch Pad.

We’re going to start with a Dynamic Beam, deleting the Color module, and adding two Emitter parameters that we’re going to set in the Emitter Spawn stack: [float] MaxDistance set to whatever amount of units would be the maximum stretchiness of your beam, and [position] SpawnPosition set to wherever you want your second end of the beam to spawn, the first one being the origin point in this case.
We’re going to set in the Beam Emitter Setup module the Beam End to our new parameter SpawnPosition and tick on Absolute Beam End and Start since we want this to be in world position. And we create a new Scratch Pad module in Emitter Update to be updating this Spawn Position parameter every time we spawn a new beam.

So if the distance between our Simulation Position and our Spawn Position (the length of our beam) is bigger than the Max Distance we set as an input value then we get a new Spawn Position – a new beam, if not then we pass what we have. In our Emitter Spawn we’re setting our Spawn Position to have a random value offset from our Simulation Position and we’re going to do the same here but for now lets just keep it static. What we set up in Emitter Spawn is just for the very first beam, this helps avoid clunkiness that you’ll find if you skip that step.
I also matched the lifetime of the beam with the emitter’s lifetime for now.

Next step is get it to stick to the floor, so we’re going to need to create a [float] User Parameter so that we can edit it through Blueprints or per instance and add it as an input in our scratch pad. I’m naming mine Z_level and keeping it at 0 for default since that’s where my floor is.

After adding this it should be sticking to the floor nicely but if you drag the system higher up so that the beam ends up being longer than your Max Distance it’s going to freak out and do a lil dance for you, so now we fix that.

We’re going to add a Kill Particles module to our Particle Update stack and set it to Bool by Comparison which is going to mirror what we did in our scratch pad: if DistanceFromSpawn is greater than or equal to MaxDistance then we kill this beam. Now when it stretches too long it’ll die and we have to wait for the emitter to restart for our next beam, but we don’t want that so we’re switching our Spawn Burst Instantaneous for a Spawn Per Frame module. In this module we’re going to set the Spawn condition to the same one we have for killing our particles.

I have also made it be infinite particles since we’re killing them when it stretches too long and we want them to remain when staying still.
Now that we have the main mechanics of the beam down it’s time to make it pretty. The main thing that gives it the stretchiness look is the dynamic width update. Lets start with our default Beam Width, were we’re going to be using the Normalized Exec Index for the Curve Index so that we can shape our beam as we need it. This is how I set up mine:

For the dynamic width it’s a bit more complicated, but lets break it down.

First we want to add our favourite division DistanceFromSpawn / MaxDistance as our Curve Index to a regular zero to one soft curve, since everything depends on how long our beam is. So as our beam shrinks in length it also shrinks in size, but now it’s way too uniform so lets add a Sine curve for our Scale Curve with a Normalized Angle of Normalized Exec Index since we want this to affect our curve throughout its length, not through age. This will give us a hourglass, so lets change the Period to 2. That’s better but it’s kind of the opposite of what we want, we want the thickness on the edges and the slim part in the centre, so lets get all of that into a One Minus operation. That should start to look like a proper stretch now! But when it’s about to break out the centre part disappears too early, so lets lower our Sine scale to 0.9. And for the cherry on top lets get a Remap Range in there, it helps a lot to give stretchyness to the end bits.

Then we finish drawing the owl:

I slapped in a slime material and a Generate Death Event with the conditions from the next screenshot so that it doesn’t keep spawning the drops whenever the slime isn’t connecting. It has a slight bug in that if you move it only in the Z axis up and down it won’t always spawn the drops but I think that’s a very specific case and generally it wouldn’t be an issue. Wouldn’t be too hard to solve but for my purposes and this tutorial this works.

I might make a hanging slime tutorial next. I’ve been toying with using a Pendulum Setup from Unreal’s Content Examples because I’d love to have a slime asset pack but it isn’t quite behaving how I want it to yet. The slime pack would also include hanging slime that connects two points and has physics in a similar way that this one does, so that’s also a possible future tutorial.

Hope this helps!

P.S. This is how I made the slimy text for the banner.

Leave a Reply