Let’s Make: UE4: Fading Scenery
Environment fades away if it gets in the way of the camera’s view of the player.
LET’S MAKE a fading scenery system, in which the objects that sit between the player model and the camera are quickly faded away. Many games use this for a 3/4 perspective which makes moving behind objects or into interior areas much easier to view. The version we are creating is basic and focuses on fading only the environment that is currently needed by the camera by the use of tracing. The fading itself will use a custom actor component which allows us to modify the static mesh actors in a scene rather than needing to add in a separate custom blueprint actor instead of meshes.
- Fades entire mesh between the player and camera
- Unreal Engine 4.7.6
- Blueprint Only
Note that we are switching between two materials on the mesh by using our custom actor component and avoiding any multiple meshes. However, I am still investigating better ways to accomplish the actual fade without requiring two separate materials per unique mesh.
If I find a better solution from the forums or from Epic I’ll include it within this post or another to help bridge the gap from basic prototype to more fully featured idea.
I also would like to note that you can extend the static mesh actor and create a custom mesh that will fade in a similar way. Because the Custom Component Actor is a feature I haven’t used quite yet I figured I would try it out.
I created my version using the basic Third Person Template as a base so I can have a character and camera already setup. Once we have the project setup we need to create a number of new actors for the fade system.
*Ignore the pickup and game mode blueprints for this tutorial
Create the following assets within the content browser:
- Actor Component
- Float Curve
- 2 Materials
- (Already present in 3rd person template)
New to Unreal is the ability to create custom components, these can be added directly onto actors within the editor so a new blueprint for the object is not required. In order to create the custom actor component we create a new blueprint in the content browser and find the actor component class to extend.
If the component is setup properly it can be added to different types of actors and still have the same effect making it very useful in this form. Our version will only be setup for static meshes at the moment but it can easily be extended to work for others such as skeletal meshes.
Float Curve / Materials
Below shows how to setup each of the 3 elements we will need before moving onto the more complex parts.
The Float Curve
This curve is a simple ease in and out and will control our fade over time. We will use this curve and move back and forth between 0 – 1 using the value output on the curve as our opacity.
Values at one being fully visible and values at zero being fully faded.
You can change up how the curve works but I have my zero time only go down to about 0.125 meaning my meshes are never fully invisible. I like this better as the player can still see a bit of the mesh once its faded but are still able to easily see through it.
Within the fade material’s properties, set its blend mode to Translucent, this allows the translucency slot to open up and where the scalar parameter will be connected. Next change the Translucency Lighting Mode to TLM Surface which allows all the shadows and basic lighting to remain on the object when we switch out to this material.
Overall the two materials are very simple and are only created like this so we can test our fade. Normally we would need a mesh to have a material with its own diffuse textures, normal maps, etc. all created in a unique way within the material graph. Once we have this we will need to duplicate it and create a fade material version, setting it up as translucent and adding a scalar parameter labeled “Fade”.
As said before, when the mesh begins to fade out the component will simply switch the materials on the mesh for the fade version and begin to update it over time. When the mesh needs to return to normal it will fade back over time and then switch its material out for the normal version.
The last thing we need to setup is the zoom keybindings within our project settings. You find the project settings within the settings menu on the main toolbar in the editor. Once there we need to create two new input keys within the input tab, one to zoom in and the other out using the scroll wheel up and down.
*Depending on your game you may not need zooming but for ours we are using the third person template and need to zoom in order to test our fading.
Third Person Player Character
Within the third person character we have a lot of basic code already setup to handle movement but now we need to setup our fading system. We will need two static mesh actor variables in order to keep track of what is currently being faded, three new functions, and finally we need to turn off camera collision which is found under our camera arm details.
The collision is a simple check box found under the camera arm’s properties. We really only turned it off as we won’t want our camera to collide ever. If the game we were creating needed both camera collision as well as checking for specific objects to fade we could create our own trace channel under the Project Settings -> Collision for our objects we will be tracing against, setting the specific meshes collision to stop that trace channel, but at the moment it isn’t needed.
The two variables created are empty arrays with the type of Static Mesh Actor. These two will store what meshes are currently in the way of the camera and the previously actors from the last check. We need both so we can un-hide the meshes that are no longer in the way by checking the previous against the new ones.
The main function we call is Update Fade Actors. This function is called on a loop, we can do it every tick but it isn’t really needed, instead I use a timer which calls the tracing less often depending on the loop delay time.
Use the Event Begin Play node and hook it up to a Set Timer Node within our event graph shown below.
The UpdateFadeActors function is one we will now create ourselves, so lets create it and double click it to open it. Because the function is being called from the timer we don’t every have to place it within the event graph, it will automatically find and call it each time our timer loops.
Each time the UpdateFadeActors function is called we start by clearing our current mesh array and then completing a trace from the camera location to the player location, grabbing all of the objects in between. I used the Multi Capsule Trace by Object node to do this as the Trace by channel only gets the first actor and stops.After we get all of our actors we loop through the list with the forloop node and make sure all the hit actors are static meshes. Again, we can change this later so it can use multiple actors, not just static meshes, but for now its good enough. If we don’t hit anything we branch down to our second function, Set Show Meshes which we will get to later.
As long as everything passes the cast we add it to our list. I used an add unique node which makes sure we aren’t doubling up on any actors but we shouldn’t, this is just a precaution.
Finally we run through our last two functions. Set Show Meshes will find any old actors that are no longer in the way of our trace and let them know they should fade back in to be seen. If we branched to this function earlier we will be setting all previous meshes to be shown as nothing is currently in our way.
The Get Component By Class will use our custom component and the Toggle Hide Mesh will be created shortly so don’t forget to add it in here once setup in the Actor Component section below.
Set Hidden Meshes does the opposite by setting the new blocking array to start fading. Again, the function at the end called Toggle Hide Mesh will be created in our component.
Within our Fade Component is where we do all of our material work. First we need a number of new variables and a function. We need a Boolean to check if the mesh is currently hidden or not, two Materials, a Material Instance Dynamic for the fade, a float curve, static mesh actor, and three floats.
We will go over each of these variables as we get to them.
Fade Material and Curve
The two variables highlighted above should be set to public by clicking the eye. This allows us to use a specific material and curve based on each mesh we add the Fade Component to. Setup the default for the fade material to use the M_FadeMaterial we created earlier as well as the C_BasicEase to use our float curve.
Toggle Hide Mesh Function
This is where we attempt to hide the mesh or show it. The initial branch checks if we are already hidden or showing instead of running through the entire function. After this we update our hidden bool and set to fade material if true. We don’t change the material back to the normal material here as we want it to fade back to opaque before hand.
When the component starts up we need to do a few things, instead of having an Event Begin Play components have an Event Initialize Component. Go ahead and add this node in the event graph. Here we get our owner, which should be a static mesh actor, casting it and adding it to our Parent Mesh variable.
Again if we wanted something other than a static mesh to work we would need to do some extra work here to set it all up correctly.
After this we can use our newly set mesh var to get its original material so we can use it later. Finally we create a new Material Instance Dynamic so we can update the fade on each mesh independently from the others.
Once we have everything setup we can update the fade and finally get to see it working in action. From the tick I have a delta time variable I like to update so it keeps the graph cleaner but isn’t required, you can just connect delta time to the nodes directly.
The branch allows us to figure out what direction we should be going, either fading out or fading in. This section could also be created a bit better by checking if we are done adding, already at 1, or done subtracting, at 0, so we don’t call extra code. Right now we simply go through and clamp everything which should be enough for this version.
To get the new value we are simply adding the Delta Time * Rate to our current amount. The Fade Rate I have is currently set to 4.0 and thus it fades quite fast. This is better for gameplay as we don’t want the player waiting to see his character for very long.
After we get our new value we set our Current Fade Variable and run it through our Curve to get the ease in and out value, setting the material Scalar Parameter “Fade” to it’s new value.
Finally the last branch will check to see if we are returning to show the mesh and if the opacity is at 1 meaning visible. If both of these are true we set our material back to the original.
In Unreal Engine 4.8.1 the Get Material and Set Material nodes require referencing the static mesh component first before getting the material or setting it. This was the case in the previous versions as well and the StaticMeshComponent can be seen in parenthesis but now the get node appears to be the way to do this. Just to keep up to date here is the updated code for those nodes below.
EDIT Accessed None Parent Mesh:
At this point in time a few people have gotten the error “Accessed None: Parent Mesh” however I have yet to reproduce it. This error could be from the actor trying to access the parent mesh before we are finished setting it up! So lets fix that, and if anything we can add this to our blueprint as a precaution if you aren’t having the issue.
We fix this by checking if we have the variable filled before we try and access it. We can do that by adding in the IsValid node or by using the the Validated Get node. I’ll do it in a few places, one in the Tick to make sure we have the Parent Mesh already as well as in the Toggle Hidden function.
Hopefully this helps alleviate the issue.
Finished Actor Fade
At this point we can grab any static mesh in our level and add our new component to it. Those we don’t want to fade out, like small props or low foliage, just leave as is.
Again the system isn’t perfect and I will be posting it to get some feedback on better practices but should help get people going. It does help by avoiding double meshes, one with the main material and one with the translucent, and by using the actor component this version is flexible and easy to add to static meshes already present in the level.
Things that need to be changed:
- Support meshes with multiple materials by using arrays instead of a single material variable
- Support other types of actors like skeletal meshes or other custom blueprints
- Fade out groups
- Allows interior sections to fade the roof sections of a building all at once, etc.