Hello fellow VFX artists! I’m Pew, a self-proclaimed VFX professional with almost 3 years of experience. Today I wanted to ask you guys for some feedback on my recent VFX project, referenced from KJ’s Stoic Bomb. I also wanted to cover my workflow as an artist so that you, too, can make effects like me!
First of all, I will share the link to the video showcasing the ability:
Let’s now move on to what went into this effect.
First of all, I should probably cover the plugins I use;
For particles, I use VFX Editor by VirtualButFake. Some of you might prefer VFX Suite by PrimeVoxel, though.
To make animations, I use Moon Animator 2 by xsixx
I also recommend VFX Scripter Pro by rabbi99 and Lumina by Mqxsyy
As for modules, although I didn’t use it for this specific ability, I highly recommend VortexFX by Aeresei for mesh-based effects.
I also have a few custom-made modules which I won’t be covering just yet.
Generally, when I make abilities like this, I spend a lot of time conceptualizing, but I had a reference for this project, so I went straight into creation instead. However, if your idea is unique, don’t worry if your concept isn’t perfect; the best ideas always come during creation.
If you watched the showcase video, you can see how the particles are synced with the player.
To achieve this, you can create a general part with all the different particle effects and then weld it to the player’s HRP with a Motor6D. Your animator of choice will treat the particle part like a limb, and thus allow you to animate it. During runtime, if you weld a clone of the part to the player and run the animation, it should get animated properly.
To toggle/emit particles, I have an extremely simple module that loops through an instance’s descendants and toggles or enables them.
To toggle, you’d have to do something like
particle.Enabled = not particle.Enabled
And to emit, you should do something like
particle:Emit(particle:GetAttribute("EmitCount"))
(Please do note that emit count is an attribute that doesn’t exist by default, so if your emitter doesn’t have it, it will throw an error)
Okay, but how do we know when to emit the particles? For this, the best option is to use animation events.
Animation events are simply keyframes with special names.
In Moon Animator, they’re easy to find and add, but if you’re using Roblox’s animator, what you have to do to add one is right-click and find “Add Animation Event Here.”
To detect when we go over an animation event, you have to use
track.KeyframeReached:Connect(function(kf)
Where “track” is your AnimationTrack. “kf” is a string equivalent of the event’s name.
To fire functions, you can store them in a table under their respective event names. Here’s an example of how I did it
local funcs = {
Punch = function(args : {})
if args.Bool then
print("PUNCHED!")
end
end,
}
track.KeyframeReached:Connect(function(kf)
if funcs[kf] then
funcs[kf]({
Bool = true
})
end
end)
Okay, so what the heck is going on in this code? To put it briefly, we first check if funcs has an event named after kf. Then it calls the function and provides a table (args) with the boolean value “Bool”, which allows the function to print. This boolean is not necessary, but just an example of arguments the functions might need. If you had more functions and they, for example, needed the HRP, then you could store HRP = Player.Character.HumanoidRootPart
inside the args table.
This solution is by no means perfect, but I could skip unnecessary blocks of if and elseif statements with it, so good enough.
There are many intricacies to creating visual effects, and I hope I’ve taught you something new. There are still many things to say about this effect, but they’re beyond the scope of this post.
Lastly, if you have any feedback, whether it is on the effect I made or this post, I would be glad to hear it. Should I make more posts like this in the future?