Welcome back.
Now, one of the last things I'd like to cover in this section is what happens when we run behind things.
We have obstacles sometimes, and the default behavior is for the camera to zoom in.
Now, for some types of games, that's fine.
I like that.
But for other types of games, in particular the top down genre, that's not fine.
I don't like it.
I'd like the camera to be essentially fixed.
I mean, it follows the character, but a fixed camera is not going to zoom in.
It's going to stay back, which means that there might be geometry obstructing the view.
So I'm going to make all of my geometry in the world, ignore the camera.
So it's kind of convenient that all of my meshes here are in the same folder as I can just change all
of them at once.
So selecting all of them, I can go to their collision settings and just have them all ignore the camera
channel.
So we're going to go to Collision Presets, set them all to custom and have them all ignore the camera.
And now if I press play, they're not going to block the camera.
But now they're blocking our view.
And that's not good either, right?
So how do we get around this problem?
Well, what a lot of top down games do is they fade out the geometry.
That's the kind of approach that I like because as you're moving behind something, that obstacle fades
out and you can see through it.
That's kind of cool.
And so we're going to come up with that kind of a solution.
Now, something like this tunnel here is a prime example of why we'd want this.
In fact, if we just delete these two pieces and duplicate these shorter pieces and use those instead,
then select everything and move it down a bit.
Now we can see that the problem becomes even more of a concern.
So I'd like to handle creating some kind of actor that we can use to dynamically fade out itself.
So we're going to make an actor for that.
And just like our flame pillar, this is something that is more of a visual designer centric sort of
mechanic.
So we're going to make a blueprint for this.
I'm going to put my fade actor here in the actor folder.
We'll make a sub folder called Fade Actor, and we're going to make a base class for all of our fade
actors and we'll have a new fade actor for each thing that we wish to have the capability of fading
out.
Now let's make that actor.
It's going to be a new blueprint based on actor.
It's going to be called BP, Underscore fade actor.
And our fade actor is going to be simple.
It's going to have a static mesh.
So we're going to add a static mesh.
And we'll just call this mesh and I'll give it a default mesh.
I'm going to give it the perhaps beacon.
And now we just need a way to fade out our actor.
So how are we going to do that?
Well, there are a number of ways we can approach this.
I'd like to approach it from the material side, so I'm going to browse to the material.
It's called M Beacon.
It's actually using a material instance, this particular mesh.
But I'm going to go into M Beacon, the material, not the material instance, but the material that
this material instance is based on.
So here we have a few nodes and we have a material, but I'd like to be able to add the ability to fade
this thing out now in order to be able to fade out the material again.
There are a number of ways to do it, but we want to be careful because there could potentially be a
lot of these in the world.
So changing our type of material could make things more expensive.
One way that we can fade things out is by using opacity and opacity mask.
Now, if we change our blend mode from opaque, we can change it to masked or translucent.
Now masked is going to be a lot cheaper than translucent, so we would prefer masked, but I'd also
prefer not to use a masked material unless we're actively blending out.
So I'd like to have not only my M Beacon and its associated material instance, but I'd also like to
have a fade version that uses masked as its blend mode.
So I'm going to right click on M Beacon and duplicate it and we'll have a fade version.
So this will be M Beacon underscore F for fade.
You'll thank me later for not typing the full word fade because we're going to be doing this for a number
of other materials.
So this is the fade version.
Let's open that.
And here in the fade version we're going to change its blend mode from opaque to masked.
And now we can see if we can figure out a way to fade out.
Using an opacity mask, you see, opacity with a default value of one means that we can't really see
through this material.
And by the way, we can preview this on a given mesh.
If we go to that mesh, for example, we can select some beacon and then come back here in the material
and click on the bottom right icon so that we can preview this with a preview mesh.
Now opacity has a value and we can hold the one key and left click to stick a value into opacity mask
with a value of zero.
Notice it's gone with a value of one notice.
It's back with a value of 0.5.
However, look, it's just the same as if it were one.
And as soon as we get down below a certain threshold, it disappears.
So it's almost like on or off, we can't really fade, right?
So how do we get around that problem?
Well, one way is a node called dither temporal AA.
So this dither temporal AA will sort of dissolve a texture.
If we plug in our value into it, then if we right click on the node and start previewing it, we'll
see that this is what it looks like, kind of almost grainy.
It's like a black and white texture with some sort of static in there.
And if we change that value to say one, well, it's all white, zero is even darker.
0.5 is somewhere in between.
So we can see what this does for us.
Now I'm going to stop previewing it and instead hook it up to my opacity mask.
And now we can really see that you can kind of see through it At 0.5, at 0.1, you can almost not see
it at all.
And at one you can see it completely.
Now, if this were a material parameter, then we could make an instance out of this and then we can
change that dynamically.
So I'm going to right click and convert this to a parameter and call this.
We'll just call it fade and apply that.
And now if we make a material instance of this material in Beacon F, we can right click create material
instance.
I usually prefix these with me for material instance, but in this case, because I want to create quite
a few of these and don't want to have to rename a lot, I'm just going to leave it to Beacon F underscore
inst.
Now I'm going to open this and because I have this fade parameter, I can change it.
I can bring it down to close to zero and see that it fades out in this nice way.
Pretty cool.
Now random is going to change how it fades.
And if you want you can change this random value.
Its default value is one and we can put a value between 0 and 1.
So if I apply that and come back and play with this, you.
You can see what it looks like with a different value.
But I'm okay with leaving that at its default value of one.
Just mentioning that that's a parameter there.
So now I have this material instance that can fade out when it's at one or higher.
It looks normal, but as we fade it out, this is what it looks like right now.
By the way, this pillar, the beacon, has a glow parameter.
And if you raise that, check that out, we get some glow on our rune.
So just pointing that out, something kind of cool.
But now that we have this fade parameter and we can fade this out, we need a way to do this on our
fade.
Actor Now one thing about meshes is they can have multiple materials.
In fact, their materials exist in an array on the mesh.
If we go into our fade actor, I don't need my flame pillar.
I'm going to close that.
My fade actor shows in the details panel the mesh and the materials and it says Element zero.
Some meshes have more than one, so we need to take that into account.
If we're going to make this fade.
Actor We need to treat materials like arrays.
In fact, if we go into the event graph and get our mesh out here and type get materials dragging off
of it, we have get material and get materials.
This returns an array of material interface object references.
So keep in mind that a mesh can have more than one material.
Our fade actor is going to take that into account.
Now, the first thing I'd like to do is get those materials used by this particular mesh and store them
in an array, because if we want to change a material instance dynamically, we have to create a dynamic
material instance and assign that for our materials on the mesh and change those dynamic material parameters
at runtime.
And if I'm fading out and fading back in, when I fade back in, I'd like to replace the materials with
what they were originally.
So they're not always using the masked material.
They can go back to their opaque or whatever they were using originally.
So in the construction script, I'm going to get my mesh and get its materials with get materials.
And store this array.
I'm going to go ahead and drag off and promote this to a variable.
And I'm going to call this original materials.
Now, this is in the construction script.
So every time we change something, we're just going to store all those materials.
Now that I have these stored, I can loop through all of these materials.
I can use a for each loop.
And in this for each loop, what I'd like to do is make a dynamic material instance based on these.
So what I can do is right click and use create dynamic material instance.
This requires a material interface object.
That's what we have.
So for each iteration of the loop, we're creating a new dynamic material instance.
We can leave creation flags at none and we don't need to give it an optional name.
Now, each time we do this, I'm going to want to store it in a dynamic material instance array.
So I'm going to make a new variable and call this dynamic material instances.
And this can be of type material, instance, dynamic.
So we're going to search for that.
It'll be an object reference, but we're going to change this to array right here in the details Panel.
Next to variable type, we're going to select array and we're going to take that array.
And we're going to call Add unique on it.
To add our new material instance dynamic to it.
Now this is done in the construction script, so we don't want to fill this up unless we're going to
use those materials.
So what we can do first thing is clear this array, because we don't know how many times this is going
to be called.
So we're going to take dynamic material instances and call clear.
That way.
Before we go and fill it up, we make sure we clear out whatever we had before.
So now that we'll have our dynamic material instances created based on our original materials, we can
now create the capability to change those material parameters.
So here's what I'm going to do.
I'm going to go into the event graph.
We're going to use event begin play, and I want to loop over my dynamic material instances.
So I'm going to use a for each loop and for each of these I'm going to now set my meshes materials to
these dynamic material instances.
So I'm going to get my mesh and I'm going to call set material and set material takes an element index.
So as we're looping through this array, we're going to use the array index as the element index.
So we're going to hook that up.
And the array element is a material instance dynamic.
We can hook that in and then our mesh will now be using that dynamic material instance.
Now this action here could be its own function.
Basically what we're doing here is we're setting the materials to the dynamic instance.
So I'm going to right click on this and collapse it to a function and call this set materials to dynamic
instances.
Now, as soon as we've done that, we can now set the parameters on these dynamic material instances
so we can take that array of dynamic material instances.
We can loop over it with a for each loop.
And we can set parameters on it.
For example, we can take the array element and we can call set scalar parameter value.
Now this requires the name of the parameter.
And if we go back to our instance, it's called fade, the one I'd like to change so we can change this
to fade and I can set its value to say 0.5 and hook that in.
So now if we have a fade actor on begin play, we should see it faded to about half way.
So I'm going to save all I'm going to browse to my fade actor and drag one into the world.
I'll put one right here.
Press play.
Now I don't see anything, so I'm just going to make sure my dynamic material instances array is not
empty.
So on begin play.
I'm going to get its length.
It should be one.
But I'm going to print that out.
So printing out the length of this array.
Okay.
So it does contain one element.
It's not empty.
Let's see what it looks like.
At 0.5, it should look like this half faded out, basically.
But of course we're not using Beacon.
Instead, we're using the other material instance that we started with.
So really, we need an array of material instances that we can create our dynamic material instances
from here in the construction script, as we can't really use the meshes materials unless we want the
mesh to have those materials from the start.
And our fade versions are based on a material using masked mode.
And I don't necessarily want to use masked except for when we're fading in and out.
So fade actors should have another array in it, and this will be our material instances and more specifically,
our fade material instances.
And this can be of type material instance.
So we're going to change it to that type.
It's an array and this is something we'll have to set and we'll have to make sure to set it in the correct
order.
So if I compile in my fade material instances, I can click plus to add and I can add my m beacon inside
my fade version of the material instance, I can set that there and in the construction script, rather
than looping over our regular materials, we do want to store those in our original materials, but
our for each loop should loop over our fade material instances instead.
Now, if we hook that into our for loop, we're making a dynamic material instance from each of our
fade material instances, and that's going to give us the result we want.
So if I go in, save all press play now I see that it's faded half out.
So that looks pretty cool.
Okay.
So now that we have the ability to set the material instance parameters dynamically, we don't want
to just do it in begin play.
We want to be able to change it at runtime.
Now I don't want to use Tick.
In fact, we don't even need to start with tick enabled.
I'm going to uncheck that.
What I'd like to use instead is another timeline.
So I'm going to get these unused nodes out of the way and I'm going to make a timeline for fading.
So I'm going to right click, I'm going to create a new timeline, and this will be called our fade
timeline.
And the fade timeline is going to have one track.
It's going to be called Fade.
And we'll have two keys on it.
Now, how long we want to fade is up to us.
I'm going to use perhaps half a second.
Maybe one second while testing.
So the length will be one second long.
The first key will be at zero and one.
The second key will be at one and zero.
So this is a fade out timeline and we can highlight both of these, make it an auto curve so it's smooth.
And now we have this one second curve that fades out.
So back to the event graph.
If we play this timeline, I'm going to click play from Start.
And by the way, if I check use last keyframe, this will work nicely in reverse as well as we can reverse
from the last keyframe we were at.
But here in update, I'd like to set the parameter values to the fade on the curve.
Now this set materials to dynamic instances.
This doesn't have to be done.
Every update.
This can be done before we start the curve.
So I'm going to put it right here before play from start and on the update, we're going to loop through
each of our materials.
There's only one in this actor, but we're going to use the fade amount and set the scalar parameter
value.
So we should see our pillar fade out over the course of one second.
And there it goes and it's gone.
Pretty cool.
So I'd like to make this a custom event.
So I'm going to right click custom event and call this Fade Out.
So now we have a fade out event that we can call to fade out, and I'd like a fade in event.
So I'm going to make another custom event called Fade In, and this one can play in reverse.
And in fact, our fade out doesn't have to play from start.
If we play and use the last keyframe, then we can fade out and in and it doesn't matter where we are
on the curve, we'll resume where we last were and go forward or backward, depending on if we're fading
in or out.
Now, if we're fading back in, we've already set the materials to use the dynamic instances.
But really, I'd like to set those materials back to their original materials because those might not
be masked, they might be opaque.
So what I'll do is when our curve is finished, if our fade amount is back to one, in other words,
we'll do a greater than or equal because I never do equals with floats.
If it's greater than or equal to one, we'll have a branch here.
And on finished.
This means we've just finished fading back in.
So in that case I'd like to take my original materials and do a for each over them.
And for each of them.
I'm going to take my mesh and I'm going to set its material.
So call set material.
And we'll set the materials all back.
So we're going to use the array element and the array index in the for loop.
So this is basically resetting all the materials back to their defaults.
So this can be its own function.
I'm going to collapse it and say reset materials.
That's good reset materials.
Okay, so now we have a fade out and a fade in so we can test this out by calling fade out and begin
play and then perhaps doing a delay by a second.
I think our timeline is one second long.
Yes.
So we'll do a second delay.
And as soon as that fade out has completed, we'll do a fade in.
And we'll see that mesh come back.
And by the time that finishes, we should reset the materials to their originals.
All right, let's save all and let's see this fade out.
There it goes.
And it's back.
So we now have the ability to fade out and fade in.
And that's great.
Now I'd like to take collision into account.
You see, if something's faded out, I want to be able to move my mouse and say there's an enemy back
there.
I'd like to hover over that enemy.
And if this wall is faded out, I don't want it to block my cursor Trace.
I want to still be able to trace through it.
So while faded out, I want this mesh in my fade actor to ignore visibility and when I fade back in,
I want to block visibility.
So what we'll do here is in the finished after we've checked to see whether we should reset our materials.
If we're fading back in, I'm going to take my mesh and I'm going to call set collision response to
channel.
Choosing visibility and I'm going to set it to block We're going to block the visibility channel.
However, in our case here, we'll have another branch in our false case and we're going to check the
fade amount to see if it's zero.
So less than or equal to zero.
And that means we've just faded all the way out, in which case we're going to set our mesh to ignore
visibility.
So visibility ignore.
And so this is all stuff we can do on finished.
So we're going to highlight all of these collapse to function and call this fade finished.
Actually, I don't need two inputs, do I?
These are both the same.
So what I'm going to do is control Z that and to fix that, what we can do is we can have a root node
and have this come out of it like that.
And then highlight these again including the reroute node and collapse these to a function.
And now it has a single input and this will be fade finished.
So now our blueprint is looking under control and of course, retesting.
It fades out.
It fades in.
Perfect.
Now that we have a fade actor, all we need to do is decide when to fade it out and fade it back in.
Because Beginplay is not the place to do it, right?
We want to do it as our character goes behind it, right?
So if it's obstructing our view from the camera, then we want to fade it out.
So that is something we'll handle in the next video.
Excellent job.
I'll see you soon.