This is great. Keeping UVs at 90 degrees never occurred to me but it makes so much sense it seems obvious in retrospect
Unless I'm mistaken, this is how Shadow of the Colossus handles the fur on the Colossi
Awesome breakdown Simon!
Aaron Winnenberg did a fantastic tutorial, describing the way you can create an fancy dashing effect, you can use in your action game.
I recently posted a short video of this effect to a couple of Facebook groups and the next day woke up to a flood of messages from people asking how it was done, so I’ve decided to write this tutorial. Thanks, Kirill and 80lv for providing a platform in which I can share this information! Also, thanks to Noa Barlow for helping me push this effect to where it is now.
The effect got to where it is now through a lot of back and forth iterations between the blueprints, materials and particles and experimenting between them all, but hopefully, I’ll be able to explain this in an understandable linear fashion.
Material Parameter Collections:
The most important part of the material setups I’m using is the use of Material Parameter Collections, which are, essentially, ways for Blueprints to communicate parameter values (floats or vectors) to your material.
In the Content Browser, right click > Materials & Textures > Material Parameter Collection
In this effect we’re going to be using 2 float parameters in a collection:
“GhostVisible” and “PlayerVisible”, both with default values set to 1.
These are going to determine our player’s visibility and our player’s ghost’s visibility.
This is the material our player’s ghost will be using when it’s spawned at the beginning of the dash.
Blend mode needs to be set to translucent.
It consists of some basic Fresnel masking (using a Fresnel function would work as well if you want to go that route) multiplied by our Material Collection Parameter “GhostVisible” plugged into our opacity.
This material affects the final outcome very little, and if you have a different material you want to use for the ghost, go for it. The only real important part is the MPC plugged into its opacity.
Player’s Opacity Material:
This is a very basic material I’ve made, the only important parts being that your blend mode is set to mask and your MPC “PlayerVisible” is plugged into the opacity mask.
Obviously, if your character’s using a more sophisticated material, you can set it up however you want.
When I’m using greyscale masks, I always like to combine them into the RGB channels of a single texture. There are multiple ways of doing this, but often my method is using the RGBA Combine node in Substance Designer as that’s where I often create such masks. Just be sure to change your compression settings to “Masks” after importing.
If you’re using this method, you’ll want to create a couple of switch parameters to select which channel of the texture sample you’re using.
Shading model set to unlit and blend mode to translucent.
The output multiplied by Particle Color and Particle Color’s alpha. This will give us control over the particle’s color and opacity in our particle editor.
The last bit being our opacity is being multiplied by a depth fade. This helps keep things like smoke creating harsh lines with it connects with another mesh or the camera.
Firstly, you’re going to need a sprite animation of a bird, or whatever you’d like to trail the character (and keep in mind the grid number, such as 4×4).
Note: I did not make the crow sprite animation. It was pulled off of Google a few months ago and after about an hour of searching for it again, I could not find a link (sorry and thank you to whoever originally made it). Also note, I had packed the opacity mask into the alpha of the sprite animation.
Instead of dragging the texture into your material editor, right-click in the material editor and find Particle SubUV, where you’ll select your sprite animation.
From there simply multiply the opacity mask to a Particle Color’s alpha and the texture to Particle color.
Since our Ghost, Crow and Player materials aren’t making use of any parameters, we’ll leave those be the way they are. However, we need to set up a couple Material Instances for our future particle’s dust and smoke.
Right-click on your master particle material and select Create Material Instance. Do this twice, one for the smoke and one for the dust, selecting the appropriate RGB switch parameters we set up.
We’re now done setting up our materials!
This effect is using only one particle effect with four emitters.
For the ease of making this tutorial and avoid TLDR, I’m just going to include images of the particles setups with some brief explanations. I highly encourage you to look deeper into this if it interests you.
The SubImage Index node sets up your sprite to animate. Depending on how many frames your sprite has, you may need to adjust the values accordingly.
The Skel/Vert Surface Location node is telling the crows where to spawn based on your player’s bone names/locations. You need to copy the bone names from the character you’re using in order for this to work.
The Particle Attractor node is telling the crows where to go once they’re spawned, which will be the next emitter we set up. Make sure the name of the attractor is the name of the attractor emitter you’re going to use (in my case it’s just “Attractor”).
Make sure to name this emitter the same as what you used in your attractor node.
Initial size is set to 1, and velocity set to 0.
Smoke and Dust Emitters:
These are just a couple basic emitters that I won’t go too in-depth with. It’s pretty easy to find some basic smoke particle examples online.
There’s using variations of spawn rates, sizes, rotations, and locations.
Make sure it doesn’t loop and the duration is appropriate.
Player Ghost Blueprint:
This is going to be the ghost your player leaves behind as it dashes forward.
There are multiple ways of doing this, such as using the vert/surf location in a particle to create a ghosting effect, but I’ve found this method to be the easiest with the best results.
To do this, create a new Actor Blueprint.
Add the component “PoseableMesh”, and make it the root of your blueprint (replacing and deleting the “Scene” component).
In the details panel of your poseable mesh, select your player’s mesh and apply the ghost material we made earlier.
Also, make sure there’s no collision being used for this poseable mesh.
From here we’re going to cast to our player, targeting our player’s mesh and copying its current position to create the pose we want.
Once we’ve set our mesh’s pose, we want to create a timeline to drive the values of the Material Parameter Collection we created earlier for our ghost and set those values.
Once the timeline is complete, the actor we just created is destroyed.
In your character’s blueprint, we need to add a Boolean parameter named Ghost, to make sure we can’t dash while we’re already dashing.
Use an input of your choosing to initiate the dash, and branch it through your ghost parameter.
From there we’re going to set our player’s speed to something high to fake a teleportation effect.
Once the dash has started, we need to fake our player’s invisibility by setting it’s MPC to zero, spawning our particle as well as our Ghost blueprint.
Set Actor Parameter is communicating with the Crow emitter telling it where the bones are it’s looking for. In the node, drag off from the Param pin and Promote To Variable and name it what you want (I honestly don’t remember what that’s referencing since I made this a few months ago).
Use a delay node for the amount of time we’ve decided to dash for (in this case 0.6) and then end the dash by setting the Boolean to false, bringing the character’s speed back to normal and setting the MPC value back to 1 to make them visible again.
Once this is all set up give it a try!
Since this was just me experimenting around, I feel like there are a few things I could have extended upon.
The most obvious being, since we’re using a third person character, when the camera is directly behind the character, the crow sprites wind up facing a sideways direction.
I believe this could be solved by lerping a different sprite animation based on which world rotation the character is facing.
Thanks for everyone’s interest!