Transcripts
1. Intro (Course Preview): Hey everyone, and welcome
to the Unreal Engine five, Getting started with
blueprints course. My name's James, also
known as the few studios. And I've been a marketplace creative for the last six years. And during that time
I've provided support for hundreds of Unreal
Engine beginners. And because of that,
I've learnt some of the common things that people tend to struggle with when trying to learn
game development. I'm ruined. Jing is one of the world's
most popular game engines and blueprints is it's powerful, built-in visual
programming language. Blueprints give us
the ability to code simple or incredibly
complex systems from within the engine without
ever having to write any text-based code. And is a great way to get started in the world
of Game Development. At the beginning of this course, we'll start off with
the basics variables. These are used to
store information like the player's
location, health, or stamina will learn about
the different types of variables and also how to manipulate them during gameplay. Then we'll move on to
functions, macros, and events. These are used to
keep your project tidy and efficient and make it easier to modify later on in your
project's development. Then we'll move on to
different types of Blueprint, likely Actor, Pawn, character, and Game Mode blueprints. Each one of these
blueprints come with different built-in
functionality that come with the engine that we can then
use to create our games. We will also cover
things like projectiles, which are often used
for weapon bullets, traces which are often used for interaction systems and
sometimes even Meli systems. And we'll cover Player inputs including the new
enhanced input system. And this is what
allows us to take a keyboard or mouse
button press and run code depending on which
key we actually pressed. We'll also be
covering widgets now, which is how we create UI
elements inside of them. Rule engine will
learn how to create new widgets and how to add
them to the players screen, as well as how to
change the layout and attach widgets behavior, two different variables,
functions or events, so we can control our
widgets actually do. Then lastly, we'll use all of the knowledge that
we've gained during the course to create some
common gameplay systems. This includes an
interaction system that allows our player to
interact with other objects. A damaged system that will allow our characters to
receive and send damage. A HUD that we can use to display information on
our players screen. We'll set up a response system and a crouching system as well. The aim of this course
is to provide you with detailed information about
the different features that are included
with blueprints. So that by the end
of this course, you're able to plan and create
your own gameplay systems. Thanks for listening, and I really hope you
enjoy the course.
2. Intro (Overview): Hey guys, and welcome to the
first lesson in this course. In this lesson, which
is going to be doing a quick overview of
what blueprints are, what they can be used for, and some common phrases that we'll be using
throughout the course. So to get started,
what are blueprints? Blueprints are a visual
programming language built into Unreal Engine. They're often used to define
things like character, weapon or even an MPC. Blueprints allow you to code
in the engine connecting up different types of nodes which together create
new functionality. The result of this could be
a door opening and closing, or it could be a complex
inventory system or combat system. The engine includes some
template blueprints that start with
useful existing code, like for example, our
character blueprint, which if I bring
into the level here, you can see over on the
right-hand side of the screen, it includes built-in
components, like for example, the Character
Movement Component, which controls
character movement. A mesh component which allows our character model to
be visible in the game. A camera component,
which when a player takes control of this
character, allows them to see. When getting started
with blueprints. Some common terms you'll
hear is Blueprint Classes. Blueprint objects,
or blueprint acts as an example of a Blueprint Class is our ThirdPersonCharacter
down here. Now if we hover over it, you can actually see it says
Blueprint class. But if we drag it
into our level, you can see that it creates
a new blueprint object and we can actually drag multiple of the same class into our level. Now these are two independent
Blueprint objects. If we had multiple players, each player could be controlling a different character blueprint and doing different things. But all these
blueprints are still using the same Blueprint Class, which is our
ThirdPersonCharacter Class. If any changes are made to our ThirdPersonCharacter
Blueprint class that will affect all of our Blueprint
objects using our class. So for example, if I open up my ThirdPersonCharacter
Blueprint, go to Viewport and I
just rotate our mesh, say 90 degrees this way. Hit Compile, go back to our map. You can see that our
characters are now facing a different direction. And if I go back
and just rotate it back to the correct
direction, hit Compile. You can see as again, updated, some Blueprint objects don't
exist in the game level, but instead run in
the background, storing information and running
important functionality. For example, the game
instance blueprint, which is used to store
information between levels of a blueprints like the Game Mode do
exist in the level, but are completely
invisible to the player. The Game Mode controls
things like which character blueprint class is created when a new
player joins the game. And what happens when a
player leaves the game. Blueprints are an
incredibly powerful tool that allow for
faster development, debugging and a
very user-friendly. The next few lessons
I'll be covering some of the basics
to get you started. So you're able to create some
of your own functionality, as well as be able to read
other people's blueprints, which can really help
accelerate your learning.
3. Intro (Creating Blueprints): Hey everyone. In this lesson I'm gonna
be showing you how to create new blueprint classes. We're also going to
be taking a look at the Blueprint editor. Before we get started, I'm
just going to show you how to dock the content
browser to our screen. By default, we have to click this content draw to open it. Personally, I prefer to have
it locked to the screen. So I'm just going
to click this doc in layout button here. And now we've got our content
browser lock to our screen. This is personal preference. You can have your setup
however you like, but this is how mine is going to be for the rest
of the course. There's a few ways we can create blueprints and our
content browser, we can right-click and select
Blueprint Class up here. Can also go down
to the blueprints, pop out and select the Blueprint
Class option down here. That awesome additional
classes here, but we won't be covering
them in this lesson. Those will be in
a future lesson. Another way to create
blueprints is go over to our Add button here on the left-hand
side of the screen. And you can see we've
got our same menu. We can select Blueprint Class, or we can go to blueprints and select Blueprint
Class here as well. So I'm just going to click
Blueprint Class to open up our pick class window. Here we can select what type of blueprint we want to create. Gives us a few of the
more common selection. So up the top here. So to
start with, we've got actor. An actor is basically just any blueprint that
exists in a level. Then we've got **** which has
enacted that the player can actually take control
of a character, which is also a ****. But it had some extended
functionality so it can walk around and we can
set a character model. We've got the player controller. This is the blueprint
that tells our character or a **** what our
player wants them to do. Game mode, which is how
we set what type of player controller or character we want our players
to start with. And then we've got some
components down here, which I'll be covering
in a future lesson. But essentially components
can be added to other blueprints to give them
additional functionality. And then down here we've
got our all classes. And this basically
allows us to select any other blueprint
or C plus plus class and have our new blueprint
use them as a template. So to get started,
we're just going to create a simple actor so I can take you through
some of the blueprint UI. It will start with just
renaming this blueprint. I'm going to call mine
video blueprints. And we'll double-click
this to open it up. And we'll start in the Viewport. Here is where we can set our locations for new
components in our blueprint. So for example, if I go to our components tab
here and click Add, just going to search for cube
and we'll add in a cube. Now, we can set our
cubes position. If I press W, that gives
us movement controls. If I press E, we can rotate it, or if I press R,
we can resize it. Those options are also
available up here. So if you want to use these
buttons instead, you can. And if we wanted
to, we could add additional components and set their location up in
our blueprint as well. Now if I just compile this blueprint and I
drag it into the world, you can see that the center of my blueprints at
this point here, but my cube is over here. Now that's because
we positioned it at that location from the
center further away. You can see that it updates
in the world as well. So that just gives
you a basic idea of how to use the viewport. What is used for, I'm just
going to delete my cube for now because we're
going to move on to the next part of the UI, which is the My Blueprint panel. Now we're gonna be using
this a lot where my coding. So starting from the top, we've got our graphs.
I think graph. If I double-click this, it will take us to
our main event graph. This is where we're gonna
be doing a lot of coding, at least to begin
with, before we start getting into functions
and things like that. But you'll become very familiar with this as time moves on. It starts with some basic nodes. I'll be going into these
in a future lesson so you don't need to worry too much about those right now. But you can also see
that under our graph it tells us what events
are in that graph. You can see that we've got
these four events here. They're also listed
under our event graph. So if I was to say double-click
active begin overlap, it will actually take
us to that event, which can be helpful if
you're trying to find things. Next up, we've got
our functions, macros, variables, and
event dispatchers. Now, each one of these are going to have their own lessons because they're
quite big systems and we'll be using them a lot. But this is where
there will be listed. Any functions that exist in this blueprint will be
listed under functions. The same with macros and event
dispatchers and variables. If you ever want to
create new ones, we can click the
little plus button next to functions here. We can do the same with macros, variables and event
dispatchers can also click this little
Add button up here. We can select if you want
to create a new variable, a function of macro and so on, we can create new graphs. And this is useful just
for organizing things. Say you had you had a character and you wanted to
have a graph for movement, and a graph for your guns, and a graph for
health, for example. You could do that and
that just gives you additional graphs that you
can organize stuff into. Overriding functions. We'll be covering that
in the functions video. So don't worry too
much about that. But if you want to
override a function, you can find those
options in here. Next up is the search bar. We can just use this to
search the functions, variables, and macros
for a particular word. It's always a good
idea to include key words in your variable
and function names. That way, if, for example, we were creating
a health system, we could just search for health. And that'll show all
of our functions, variables that have the
word health in their name. Next we're going to be
covering the top bar. So to start with,
we've got compile. This basically just tells us, is our blueprint gameplay ready? So right now it's
got a little tick, which means everything's good. We're all okay. But if I
was to say drag out and add a print string here and see that now we need to compile it. And this just basically allows the engines
check the code, make sure there's no issues. If there were an
issue and give us a little red exclamation mark. It also probably give us some compiler errors telling
us what the problem is. Then we've got our save that
just saves a blueprint. If we click Save and
see the little dot went away next to the blueprint
name because it's saved. We've got browser.
If we click this, it will take us to the place that the blueprint is
and our content browser. Then we've got diff, this is for source control. I'm not going to be
going into that because source control is
quite a big topic. So we're just going
to skip over that for now. We've got find. This gives us the search window
where we can search for, say, for example, a node. So if I search for
print string here, will actually tell us, hey, there's a print string
node in the graph. So if I double-click
that, it will actually take us to it. This is really helpful. If your blueprints
get quite big, you can forget where
you've put things. So you can just search keywords
to find where things are. Hi, unrelated just hides connections that aren't important
at that moment in time. Usually I just recommend
leaving this off, but you can have a play
about with it if you like. Next, we've got Class Settings. These are kind of like the basic settings of our blueprint. You probably won't be
doing too much in here. Most blueprints will have
very similar class settings. You can also adjust
the thumbnail angle. So you can change
the camera angle for the thumbnail when
the Content Browser, if yours had a phone. Now, we can also add interfaces which will be a whole separate video
that will go into. But if you want to find the interfaces that are in
class settings under here. Next we've got class defaults. Now this is where all of our
blueprints settings are. So because we started
off with an actor, actors have a bunch of extra settings that
they come with. Four multiplayer
replication for our tech, which is our techno down here, which runs every frame, we can make a few
adjustments to that. We have collision settings, rendering settings and so on. We'll be going into
these a little bit more in future videos. If you ever want to know
whether a bit more detail, what things do, you
can always hover over the name and it
gives us a taut it. If we were to create
a new variable, say I go to add and I
just didn't new variable. Let's call this test. If we now go to class defaults, we find the, oh, we need to compile first because it won't
show up until we can pull its class defaults. We'll scroll back up to the top. You can see on the
default we've now got our test variable. And that's where we can see all of our variables
default values. And those are the values that the blueprint will start
with when it's created. So I can turn that on
and off here as well. We've also got a
search bar up at the top, which is
really helpful, especially if you've got
a lot of variables In your blueprint or you're using
someone else's blueprint, you're trying to find a setting. You can search for
keywords here to find the option that you need. Then we've got the
simulation and play buttons. These basically just start
the play an editor mode. If I hit the play
button, you can see it's opened up the plan
editor window. Next we've got the
debug dropped down. Now, this is a really cool
feature of blueprints. I will have a whole
video that goes into debugging and some of the
features the engine comes with. But just to give you guys an
example of what this does, if I connect my print
string here to the tech. Now this runs every single
frame that the game runs. So if I go to our map, I'm just going to drag
the video blueprint M. I hit play. You can see that the
halo is running over and over again for every
frame that's drawn. And if I go to video blueprint, because I've got video
blueprints selected here. You can see that it's showing
me the code that's running. It's all highlighted. That's telling me that the tech note is running and it's running
the print string. And this can be
really helpful when you have large blueprints, you can see exactly
what code is running. For now we're just
going to pause that will delete our
print a string here. And it will also remove our video blueprints
from our level. Just so we've got a clean start and we'll head back
to our blueprint. One other thing I wanted to mention about the find results, actually, if we go back to find, you can see that we've still
got our window open here. If we click this
little button here, will actually search
all the blueprints and our project for
our search phrase. So if I click this,
you can see that it's actually finding a
lot of print screens. I'm sorry, Print String
nodes around our projects. And these are actually
blueprints that come built into the engine. So you can see it's searched all of the blueprints
and it's telling us exactly where print strings are being used
throughout our project. This can be really
helpful if you're again trying to track
down something. You can search all of your
blueprints all at once. Next, we're going
to take a look at the construction script. If I close my finding
blueprints window and we can go to functions, you may have noticed
the construction script that's there by default, it's built into the actor. So we double-click that will take us to our
construction script. And here we can add
code that will be run when we first drag our
blueprint into the level. So this is great for if
you're building sort of level design tools
and things like that, maybe you want to
randomize the color of something for every time
you drag it into the level. The construction script is
really useful for that. Now, if any of these
windows ever go missing or say you close them by
accident, it's not a problem. You can always just go up to the windows drop-down over here. And in here you
can take on any of these panels that we've
been looking at today. So you can turn off. So for example, if I
close my components, I can go and I can just reopen the Components panel and I
will just pop right back up. Now, the last thing I
wanted to point out is the address bar that's
up here on the top. This will always say
which blueprint urine, I'm wearing that
blueprint you are. This is really helpful if
you're following along with tutorials or screenshots
or anything like that, it's always worth taking a look, making sure you're on
the right blueprint and also say the function name
or the Event Graph name. So if I go to Event
Graph, say event graph, that will tell you exactly
where you are or if you're following along
with a video or an image, you can see exactly where
they are in those videos. So that's gonna be
it for this lesson. Hopefully you have a
basic understanding now of where thinkers and
the Blueprint editor.
4. Intro (Event Flow): Hey everyone, In this lesson I'm going to be
taking you through how Blueprint nodes run and
the order that they run in. To get started. I've set up a few examples here in our ThirdPersonCharacter
Blueprint. And I'm just going to
be talking you through these and explaining
what each one does. So to start with, we have
the event begin playing. Now this is an event
that's built into the engine and it
will run whenever our game starts or when
the blueprint is created. What will happen here is
we have our event begin play that will tell
our player a play, play a sound now to run. Now, this is a custom event
that I've created myself. And if we go down
here, you can actually see we've got the
play player sound. So I'll begin play or x cubed. It will execute our play, play a sound node, and that will execute our
play sound at location. And the sound that, that
will play is going to be wherever our
sound input is here. So that's gonna be
the start sound. Then it will play that sound at the
location we're providing. So that's the get
actor location, which is going to be the
location of our character. Then once i sound is played, our output of our
play, play a sound. Cool. We'll run. That will happen whenever the execution chain down here
has no more nodes to run. So what this will then do is we'll set our health value to whatever our starting value as code runs from left
to right typically. And if we hit an event, cool, we'll run the code that's
connected to that event. And then we'll resume executing the code with
our original event. Next, we've got the
event tech note. Now, this is a very commonly
used node by beginners. And the reason is because it runs every single
frame of your game. So every single time your
graphics card draws a frame, this event will run. Now, the problem with
that is people tend to attach a lot of
code to this node. And that can start to slow down your project very quickly, because generally,
most code doesn't actually need to be done
every single frame. We want to use things
like Player inputs, timers, and various other
ways of running that code. Instead of just every
single frame we run it because that's how you get
poor performance in your game. But for this example, I've just taken some
very simple code. I've got a number value. And then we're plotting one to that number value and then we're setting that number value. Every single time a frame
is drawn of our game, we're increasing our
number value by one. And then I've just got to
print string node here. So that will take
the number value, it converts it to a string, which is text basically. And then we print
that value to the, to the player screen. I will be going into
more detail about these events when we come
to creating some examples. But for now I just
want to explain the different types of events
and how they execute code. So next we have the
input action jump. Now, this is a node
that will run whenever our player presses
the jump input. So by default that's
the space key. And the reason that
is is because if we head over to edit and
go to Project Settings, then I'm gonna go
to Input down here. We'll go to Action Mappings. You can see that we've got an action mapping
here that says jump. If I click the down arrow, you can see that it's
got spacebar set here. So this is a default input for the ThirdPersonCharacter
project. So that's why that's
already here for us. So when I go back to our
ThirdPersonCharacter Blueprint, That's why it says input
action jump is because that inputs already been set up
in our action mappings. And what this basically
does is when I press Space, pressed will, will, will run, and that will cause
our character to jump. And then when I release,
that cools the stop jumping. Now, input actions is
essentially how you take a player's
input and we can run code using that input will be going more into
impactions in a future lesson. There's also a new
enhanced input system that comes with
Unreal Engine five. So we'll also be looking
into that as well. Another way to run code through Player inputs is using
the input events nodes. So if I right-click
and I searched for a keyboard name, say Enter. And we can scroll
through these and under keyboard events we
can find the Enter. Now, this is similar to
our input action Jump. We've got Oppressed, which will run the code that's
connected to it when the Enter key is pressed and released when
code will be run, when the key is released. Now, these are more for
debugging and quick prototyping. We will be using these quite a bit later on in the course just because they're quick itself
than our project settings. But typically you
wouldn't use these nodes. When setting up a
game's final key binds, you would use the input actions
that I showed you before. Next, we've got the, any damage
nodes, which is up here. And this event is
built into the engine. And it allows us to tell
our ThirdPersonCharacter that it's taken damage
from other blueprints. And those other
blueprints can also supply a damaged value, similar to how we called our play play a
sound event here, and we provided a start sound. Then our play, play a
sound event down here, uses that start sound and
plays a sound at a location. This is similar in that
the other blueprint can call the enemy
any damage of m, it can provide a damaged value. And now in our
ThirdPersonCharacter Blueprint, we can use that damage value to subtract from our
current health. Now are any damage event is calling a function
called decrease health. Now, I've created
this function myself. And don't worry if you don't
know what a function is, we will be going into
that in a future lesson. But essentially a
function is one node that contains other nodes and
that one node is reusable. So we can reuse that code in multiple
places and our project. So if I double-click
this function will actually take us into
the function itself. And you can see that function
contains all these nodes. Now, this will execute
similar to our event graph. So it will execute
left to right. And then once it
gets to the end, the node will be finished. So to start with, we will take our current Health value and it will subtract the damage value that we got input from any
damage of them. Then it will set our new
current health valley. And then we're setting, or sorry, we're checking, is our current health
less than or equal to 0? If it is less than
0 or equal to 0, then we run the Play
play sound node and we're telling it
to run the deaf sound. So as you can see, we're reusing our play,
play a sound node. And this time we're
telling it we want to play the deaf sound. Then after our sound
has been played, we then tell the
actor destroy itself, which basically
tells the actor to completely remove
itself from the level. Or if I hope is greater
than 0, we're telling it, we're turning our play, play a sound node to play the hertz sound instead
of the deaf sound. Now, if our Destroy Actor
node runs or if our play, play a sound with the
hertz sound runs, you can see that they
have no more outputs. So what will happen then is
our function is now finished. So if we had additional
code connected up to the output of our function,
that would then run. We don't. So this
execution chain has just ended now with
decreased health function. That's gonna be it
for this lesson. Hopefully you now understand what causes blueprint code to run and the order that
things generally execute. Don't worry too much
if you don't fully understand functions
or events yet, we will be covering those in separate lessons in the future. This was just getting the
hang of how code actually runs and what causes it to run.
5. Variables (Overview): Hey everyone, In this
lesson I'm just going to be explaining what variables are
and what they're used for. Variables are basically just a way of
storing information. And there's a lot of different
types of information, so there are quite a few
different types of variables. In the next few lessons, I'm just going to be
taking you through some of the more commonly
used variables. We'll learn how to
change their values. And also we'll cover some basic examples of common things that
there'll be used for. So to start with, we'll
create a new variable. And to do that, we'll head over to our new Blueprint panel. And there's a couple of
ways we can do this. We can click the little
plus button next to the variables tab and create
new variable that way. Or we can go up
to the Add button here and select the
variable button here, which will create a
new variable as well. Now, once we've created
a new variable, will be able to rename it. So for this variable, I'm just going to
call it new variable. Here. We can also set our
variable types. So the default is a boolean. A boolean is just a
true or false variable, so it stores either a
true or false value. Now, with our variable selected, we can add over to
the Details panel. If you don't have
the details panel, you can always bring
it up by going to Windows and selecting
the Details panel hip. So overnight Details panel, we've got our variable
names so we can rename our variable
whenever we want to. We can set the variable type. Now if I select the
down arrow here, you'll see some of the more
commonly used variable types that we'll be going
through in future lessons. There are some additional
ones and drop-downs. We won't be covering
those in the course because there are lots
and lots of them. But I'll be explaining
what they are and what they're used for in
a future lesson. Now, we have a default
value down here. This is basically the starting
value for our variable. Now at the moment it doesn't actually have any option here. It just says please
compile the blueprint. That's because it's
a new variable for that setting show
up, we have to compile. So I'm just going
to compile here. You can see that now we've got this tick box that we
can turn on and off. And that's because a Boolean
is a true or false value. So we can set where
for this variable starts with a true
value or a false value. Now there were also some
additional settings up here. Don't worry too much about
these at the moment, we will be covering some of
these in a future lesson. Now a big part of variables
is that we can actually get the information
stored in them when we're writing code and
we can change them. So there's a few
different ways you can get your variables data. So we can either just
drag it straight into our event graph from my blueprint panel
drop and we get an option for getting new
variable or set new variable. So we can do gap that will
give us this get node here. Using this node, we can get the current value that our
new variable is set to. Now we can also drag
out and do set, and that allows us to change the current value
of our variable. Now, these notes will sometimes look different
depending on the variable type. So because this is a boolean, it's got little tick box here. We can turn on and off. But say if this was a variable that we're
storing a number, we wouldn't have
the tick box there. Now another way
you can do this is when we drag our
new variable in, if I press Control
on my keyboard and let go of the
left mouse button, just instantly create
a node for us. And we can also
drag out and hold down the Alt button and let go. And that will give
us a set nodes. So instead of having to
use this little menu, you can use some keyboard
shortcuts there as well. Another way you can create the variables in our Event Graph is we can just right-click and search for a new
variable and just hit enter. And we've got our get node and we can do the
same thing with SAP. So I can just search
for a set new variable. And you can see that's
come up there and we can just create that as well. So it doesn't really
matter which way you use to create your variables
in the Event Graph, whichever is more
comfortable for you, you can just use that. Now depending on how much time you've already spent
in the engine, you may or may not know what variables can plug
into other variables. So for example, if I create
a new variable here, I'm just going to call
this one of the variable. And I'm going to leave
this as a Boolean, fight, drag that into our event graph
and I'm going to get it. I can actually plug
that other variable into my new variables set node. And I'll just move this
one out of the way. And what this will do is
it will take whatever are of a variable value is, and it will tell our new
variable to be that value. So if we had this node running, say, on Beginning play, so I'm just going to
begin playing Notre. Plug this in. Now, when the game starts, our new variable will
be set to whatever our other value other
variable is set to. So if I select my
other variable, you can see that
I need to compile my blueprint, so I'll do that. So if I set the other variables, default to true, and if
I go to my new variable, its default is false. Now, what this will do is it will tell our new
variable to now be true. And we can check this if I
add a print string quickly, connect the output of
my new variable set node into the string input. And this output is basically
the same as a node. So just to keep your code
clean or you can use that instead of having to
create a new node. So now when the game starts, we would expect our
print string to print true because that's
what our other vowel, other variable is set to. So if I can pull and I hit Play, you can see that
it's printing true. And if I was to change my
other variable to false, you'll see that when we
hit play, it reads false. So that's gonna be
it for this video. In our next few lessons, we're gonna be learning about
specific variable types and some nodes that are commonly used with those variables.
6. Variables (Booleans): Hey everyone. In this lesson we're
gonna be taking a closer look at Booleans. Boolean variables are used to store a true or false value, but they can also
be used to control which code is being
run in your project. And they can also be the
result of certain tests. So for example, if we were
checking is a greater than b, the result of that test would be a Boolean because it'd
be either true or false. So to get started, I'm going
to be creating some examples of how Booleans can control
which code is being run. And we're gonna do this and need ThirdPersonCharacter Blueprint. So I'm just going
to open that up. And in here we're going
to create new variables. So in my blueprints panel, click the new variable button, and I'm going to call
mine example Boolean. And mine is already set to
Boolean, but if yours isn't, you can just click the drop-down here and select
the Boolean type. And we're going to
compile so we get our default values show up
in the Details panel here. If you're ever missing
any of these panels, you can always turn them on up and the windows drop-down here. We're going to leave the default value is
false because we are actually going to be
changing that using code. So we'll start by
creating a tick node. So we'll right-click the
Event Graph and search for tech and we'll create
the tick event. Now, if you remember from
our previous lesson, runs every single time a
frame is drawn off our game. Next, we're going to get
our example Booleans. And we're going to
drag out from it and we're going to
search for grunge. If we spell it
right, there we go, we can search for
brands and create that node connected up
to our event tech. So now every single frame, this branch node will run. What a branch node
does is basically just check the Boolean
variable that's plugged into it and runs either
true or false depending on if the Boolean variable
is true or false. So it start with, we'll just
create some prints strings. So we'll drag out from the true. We'll search for print string. And this is just a node
that will print out some text on our players
screen whenever it's run. So I'm going to say, I'm going to set this to true. And I'll copy and paste this and connect this
up to the false. And I'm just going to
set this to false. And that will just mean
that when our true pin is run to run on the screen and
when our false pen has run, folks will run on the screen. So I'll show you now, default
value is still false. So we should expect folks
to run when we plan, the editor will hit Play and you can see
false is running. If we accept, we change our
boolean to true and hit Play. You can see that
true is running. The cool thing about
blueprints is we can actually see this code
running in real time. So if I go back to my
ThirdPersonCharacter while the game is still running, you can see the debug
drop-down here. And if I select the
ThirdPersonCharacter, we only have one
option because there's only one ThirdPersonCharacter
Blueprint in the level. So we'll just collect that.
You can see that we can see Arctic node is running every frame that's
running our branch, which checks our
example Boolean. And if we now save it, you can
actually see it says true. So true is running on our print string is running
and it's printing out true. So now we want to be
able to actually change our Booleans value during gameplay so we can change
which code is going to be run. So we'll exit out
of our play mode. And we're going to
create a new input node. And I'm going to search
for it left mouse button. And this will be run whenever our left mouse
button is pressed. And then the release will be run whenever the left mouse
button is released, will drag out and we're
going to use a branch node. Now, there's actually a few ways you can create branch nodes. One of them is to hold down B on your keyboard and then
left mouse click and you can see it
creates a branch node or you can right-click
and search for if. That also brings up
the branch node. Or you can search for brunch. And that also brings
up the branch nodes, whichever you're more
comfortable with. We're going to connect
this up to the pressed. We're going to get our example Boolean and plug that
into the condition. You can see I'm dragging
it straight on and it will actually automatically
connect it to us, to the branch node for us. And what we want to happen here is when our left mouse
button is pressed, if our current Boolean
variable is true, we want to set it to false. So I'm just going
to plug that into false and see if I
drag it onto true, it will just connect
automatically. So we want it to be set to
false if it's already true. And we'll copy and paste
this connected sub to false. And if our current
value is false, we want to set it to true. So it should look
something like this. Will compile this. And now we can test it. And again, I'll hit Play. You can see currently it's true because that's our
default value. If I press left mouse
button, it becomes false. And if I keep pressing it, you can see that it's
changing the print string. Now there's a few other commonly
used nodes with Boolean. So I want to show
you, if we head back to our ThirdPersonCharacter
Blueprint, we take our example Boolean and we drag out from it
and we search for all. You can see that we've got
a few different or nodes. So I'm just gonna be using
the OR Boolean node. And you can see that gives
us two inputs for Boolean. And then one output I want to know does is basically check, is any of its inputs true? If it is, then it
will return true. If they're all false, then it will return false. And we can add multiple inputs. So we could add additional
inputs if we wanted to. So for example, our example
boolean is ticked on true, but all of the others are false. So this will still run or, or, or Node or still output as true. So we can test this. You can see it's running true. But if I change my example,
Boolean true, false. All of its inputs are now false. So we will now return false. You can see now it's
returning false. A similar note is
the anti-nodes. So if we delete our off now, we'll drag out from our example Boolean again and search for and we can select
the Boolean node. And this works in a similar way. It takes multiple Boolean inputs and returns a Boolean output. And what this does
is basically all of the inputs must be true
for it to output true. So right now our example
boolean is false and this additional one is also
untyped, so it's false. But if I change my
example boolean to true, now we've got one true
and one false input. Now, the output will be false
because that both not true. So we can test this, hit Play. You can
see it's false. But if we accept and I
tick this option on, now that they're both true, it will output true C. Now, these are notes
that you'll be using very often with
branch nodes and they can save you having to have multiple branch nodes if you're testing more than one variable. So for example, if you need free variables to be true before you want a
branch node to run, you'd use an anode. Another commonly used
node is the node. So if we drag out and
we search for naught, we can use, Let's
see, NOT Boolean. And this basically converts or changes or Boolean to the opposite of what
it currently is. So if I connect this up, currently our Boolean
is ticked on for tree, but this will reverse
that and make it fox. So we can see is
definitely set to true, but it's going to run folks. See, if we head back and
we set this to false now are not node will
actually convert that and make it a true
while true code will run. Now, there's one other note
I want to show you guys, and that is the equals node. So it will delete are not
node now and I'll drag out, and I'll search for equals. Do one or two equals. I like to do too,
because it usually just brings up the
exact form we want. And that's r equals note here, you can see it's got
two Boolean inputs and one Boolean output. If I connect this up to
our brunch note here, this basically says that both of our inputs have
to be exactly the same. So currently they're both false. So our example boolean
is set to false and its second input
is set to false. So this will actually one true because they're both
exactly the same value. So we can test this at play. In C. It's running true even though our values
are actually false. And if I was to set our
example boolean to true, but leave this value is false. It will run false
because they're no longer the same
value anymore. And we can check this again. Hit Play. You can see folks is running. Now as a side note, as of you E5, if you were to create
these nodes that I've shown you without dragging
out from a Boolean, they actually wouldn't have
these red inputs and outputs. So for example, if I search
for r equals note here, you can see that it's
got a Boolean output because an equals node is always going to
return true or false. But these inputs are
actually grayed out. And the wildcard,
which mean they can actually be
any variable type. A few ways to convert these
into our Boolean type. So we can either just drag
out from our example Boolean, connect that up and it will automatically convert it for us. Or we can right-click
these grayed-out penta, go to convert pin. You can see we can
change it to a lot of different variable types. But you can see we've
got our Boolean option there, so we can select that. And it now converts our node
into that Boolean type. So that's gonna be it for
our lesson on Booleans. We will be using
them a lot more in future lessons as booleans are pretty cool part of coding. Don't worry too
much if you don't remember all the nodes
we've used again, we'll be using those a lot
more in future lessons.
7. Variables (Integers & Floats): Hey everyone. In this lesson we're
gonna be covering the float and integer
variable types. Now both the float and integer variables are used to
store numbers values. The difference
between the two is integers can only
store whole numbers, meaning it can't have
a decimal point value, whereas a float
can store numbers that do have a
decimal point value. Both can store positive and
negative value numbers. So we'll get started by creating
two new variable types. I'm going to create
two new variables. The first one I'll just call example float, and
the second one, I'll call it example
into integer, will change the types
so we want integer. Then for our example float, we'll select float
on which compiler. Now with our example
integers selected, you can see over in
the default value we can set a number value. So I can set this to
say 99, for example, but I can add a
decimal point and add a decimal point value. Say if I tried to do that, when I press Enter, it gets removed
because an integer could only store whole numbers. Whereas if I select my
float variable and I go to the default value here you can see it actually
really has a decimal 0. And I can set this
to 99.99 hand, and you can see that the value
actually saves correctly. Next, I'll show you how we
can set and get our float and integer variables is very similar to how we were
working with our Boolean. So I'll quickly go
through that process. I'm just going to
right-click and create a left mouse button input, like we did with our Boolean. And we'll get our
example float star with, and we're just
going to select Get Float from our pressed. I'm just going to choose
the print string node. And that will allow us just to print string our current value. When we plug it into the string, it gives us this
additional node. All that's doing is converts our flute value into
a string value. And a string value is just text. And that allows our
Print String nodes to actually print out
the float value. So now when we hit
play and I left-click, you can see it's printing
out our default value. And the process is the
same for our integer. We can just get that. I'm going to drag it straight
into our string input. And you can see it's given
us a different node, looks similar to the first one, but this convert an
integer into a string. So I'll print string
can display it. Then when we hit play
and I left mouse, you can see that it's printing
out are now integer value. Next we'll start
changing our values. So what we can do is we can right-click and use a tick node. From this, we're going to
increase our integer value. So we'll get a current
integer value. We're going to drag out,
we're going to use the plus. And this is an add node. And it works pretty
much as you'd imagine. It takes the current value of our integer and add
some value to it. So I'm going to set this to one. So output will be our current example
integer value plus one. Then we need to set
our example integer. So I'm just going to
drag out, do SAP, plug this into our tick node and plug the input into
our addition node. So now every frame, our example integer will increase and when we
left mouse button, it will print out
the current value. So it will compile and hit play. So if I hit Plus, you can see that it's
already up to 249. And that's because our tick
node is running every frame. So it's going to
increase very quickly. And see as I click that
value is going up a lot. Next, we'll do the same
thing with our float value. So we'll go back to our
character blueprint, and we'll remove this code here. And we will do the same
thing but with afloat. So we'll drag out, do so. Connect this up
to our tick node. Then we want to get the
current example float plus. So we'll use an add
node and we can add a decimal point numbers. So we could add say, 1.25 and connect the output
to our example float. So every frame we take the
current float value plus 1.25. And then the result we set
now to our example float. And then we'll plug in back down here on our
left mouse button, we'll have our print
string display, our float value instead
of our integer value. So now when we hit play, we can click and you can
see that it's going up in decimal point numbers now because we're
using our float. Next, I'm going to take
you through some of the more commonly used nodes
with floats and integers. Now the reason we're
doing these two variables together is because they're both number of
variables and they both use very similar nodes. And they can
actually be combined together with some
nodes as well. So if we head back to our
ThirdPersonCharacter, will get rid of this code up here to give us a
little bit of space. And we'll start with the basic nodes we've
already been using. So I'm just going to get
both float and integer. Now the first one is R
plus node, add node. We can create that allows us
to add the inputs together. And output the result. We can add new pins
if we want to, to add multiple
variables together. We can also create a
new flow variables such as call this a float. Set this to a float. We can plug that of
a float variable. So we can add multiple
flow variables together. Now, since you were five, we can actually change these inputs two
different variable types. So say I wanted to add my example float and my
example integer together. We could do that. Now if we've got multiple pins and we want to remove them, we can just right-click
them and remove them. So I'm just going to remove
these two extra ones. So I want to combine these
two values together. We can do that now. So we can right-click
or extra pin, go to convert pin
and select integer. Now we can plug our integer m. And now this will
output the result of example float plus
integer as a float. So we could set our example
float to that value. Now, we can test this
in game if we want to. We can put this down here. Connect this up to our
left mouse press button, will plug the result
into our print string. So now we're going to
say add 1.25, 1.25. And we'll add to that. When we hit play, we
expect it to be 3.25. And it's actually
increasing because we're setting that float value. So every time we click, we are now increasing
the value because our example float
has been increased. Now this process with
converting one of the pins to an integer can be used with most of the nodes that I'm
gonna be showing you. So if we continue, I'll get another
example, float hair. If we drag out and we
do search for multiply, you can use this symbol here, or you can search for multiply. That gives us a multiply node. This works as you
probably imagine. It takes the inputs, multiplies them together,
and returns an output. We can right-click one of the inputs and convert it
to an integer as well. Now, you may have noticed I'm doing it so that the
output is a float. The reason I'm doing
that is because if we did this the
other way round, so if I copy and paste
my integer here, and we created an ad node. If I convert this to a float, you can see that the
output is actually now changed to a float even
though it was an integer. The reason this is
happening is because our, if this was a integer output, we would lose whatever value, whatever decimal point value or float variable might have. So it automatically changes
that now to a float. So carrying on, we
have multiply node. We can also do this
with our integer. So if I delete this ad note
here being dragged out, we can search for multiply, multiply node, and
that will give us a integer multiply node. We've also got the
subtract nodes. So if I just delete
these notes it, we can use a subtract node. And you can search for
the line symbol here, or you can search for subtract. It's up to you. And that gives us the same
thing as our addition node, but there's subtracts the
inputs and returns the outputs. Again, we can convert
these inputs to a integer, or if we wanted to
on an integer node, we could convert it to a float. And just like before, it's converted the
output to a float again, because we've added
a float input. So those are the
basic ways we can manipulate our variables values. We can set those new values. But there's also ways that
we can check our variables. So if we get rid of these
minus nodes for now, There's also nodes such
as the greater than node. So if I drag out
from my integer, I search for greater than. You can see, we can either
search for greater. So if I search for greater,
you can see it comes up, or you can use the greater than symbol and create this node. And this gives us
two inputs that are integer and an
output that's Boolean. So this will basically check, is the a value, the top value greater than the b value or the bottom value. If it is, then it will
return a true boolean. And if it's false, it will
return a false Boolean. Again, like our previous nodes, we can convert the input pins. So if I do convert, we can
change this to a float. So we can actually check to see is our integer greater
than our float value. And that will return out
still a Boolean value because this will always
be either true or false. We can do the same
thing with less than. So we can drag out
from our integer and do the less than symbol or
we can search for less. And that gives us the
same node but reversed. So if a is less than b, then it will return true. If a is greater than b, it will return false. There's also greater
than or equals nodes. So if I do the greater than symbol in C that we've
got greater equal. And this just checks, is a greater than B or is it? The same as B. If it's greater than b,
it will return true. If it's the same as B, it
will also return true. And if it's less than b, it will return false. And then we have the same node, but with less sun as well. So we can do less than equal. And that does the same
thing but in reverse. So a must be either the same as our bottom value or less
than our bottom value. And that will return true. Now, because these nodes
output a Boolean variable, we can actually use these to say Boolean variable like we were doing in our
previous lesson. So if I create a new variable
and call it Boolean, we can use these greater
than nodes or less than nodes to set a Boolean
variable if we wanted to. We can also use these nodes
control a branch node. So if I search for branch
and create a Branch node, like we did in our last lesson, we can control which code
is being run depending on the result of our
greater than or less than. Note. One other note that
I wanted to show you guys is the equals node. Now, this works similarly to how our Boolean equals node works. If I drag out from
my integer and I do the two equals symbols and see that creates
us a equals node. And this basically checks, are these two
integers the same and outputs a boolean
that we can then use on things like asap
Boolean node or a branch node. Unlike the previous nodes, we can also convert the input
to a float if we want to. We can choose float
double-precision because that's what
our variable was. We can connect our
example float into that. And this will check,
is our integer exactly the same as
our float variable? If it is, we return true, if they're different
than it returns false. Integers also have
another way that they can control which
code is being run. So if I delete this
code here for now, and I drag up our
example integer. If I drag out and I
search for switch, you can find switch on int. And this gives us a
note that allows us to control which output is run depending on
our integer value. So currently our
integer values is two. We have a default pen. So what will happen if I'd left mouse button right now is just our default pen would run and
nothing else would happen. But if we add a new pen, you can see it's added
a pin that says 0. If I add a couple more pins, you see that we've got 012. Now if I was to press
the left mouse button, the two pen would rum, because our integer
is set to two. If I was to change this to 0, then our 0 pen would run in testis or by
use a print string. We'll just set this to 0. I'll copy and paste this
and we'll set this one to one and this one to two. Now, depending on what our
example integer is run, the different outputs
will run if we hit Play. And I left mouse,
you can see 0 is running because I
set the value to 0. If I set it to one, then our one will run and that will run our one print string. You can see one is now running. This can be helpful
if you want to run different code depending
on what value is. And if I was to say set
this value to say 99, now there isn't a 99 pin output. So what instead will happen is our default pen will just run instead because there's no
matching output for 99. Then if at any point we wanted to remove some
of these outputs, we can just right-click
the pin and we can do remove execution
pen to remove those. Lastly, I want to
show you how we can use a float to set an integer. Now, this is a little bit
different from normal, as our float could have a
decimal point value winner, and our integer can't
store that value. So we have to either round
up or down or float. So if we get our
example float here, we set our example integer. We connect this up to our
left mouse button here. We can drag out and plug
straight into our integer. But that's gonna give
us this node and this will round up, round down or float value. So if this is say, 1.25, it will round that
value down to one, and then it'll say
integer to one. So if I added a print
string here so we can see what the result is in game. We expect this result to be one when I left mouse, which is, and even if I set
this value to 1.99, it will still round
the value down. So if I hit play again, you can see it's still rounding
that value down to one. But there are other nodes
that allow us to round off float to a
different whole number. So if we go back to our
character blueprint head and we delete the node. That's just the default
node for when we drag from a float to an integer. But we can also drag out from our float and search for round. And we can use the round node, which would just round our float value to the
nearest whole number. So if I connect this up here, currently our variable is 1.2. So when we left mouse button, we had expected to
round down to one. So if we hit Play, you can see that it's
printing out one. And if I was to increase
this to say 1.8, we'd expect it to round to two. You see that that's
working correctly. Now, we don't need this same conversion process if we want to set a
float to an integer, because floats can display
whole numbers just fine. So if I was to delete this code, we would set our float. And we got our
example integer here. I'm just going to
reuse this variable. If we plug that in, you can
see that it just gives us this little note that converts
it from integer to flow. And there's no rounding going on because our
integer is a whole number. And our float can store
whole numbers just fine. So you can see our
integer, it's 99. When we left mouse button, it will change our
float to tonight. So I'll just connect this
into our print string. So when we hit play, you will see that
it's printing out 99 because it's float
as a point value, but it's being set to the
correct value of our integer. Now, there are a lot of
other maths nodes built into the engine that we
won't be covering in this lesson because
there are a lot. But if we drag out
from our integer, you can scroll down
and find the mass. You can find all
sorts of nodes in here that you can play
about with if you want to. Most of them are
pretty specific, so you probably won't be
using them too often. But what I've shown here are the more commonly used nodes. And you can do the exact
same with the floats. If I drag out from there
and we just scroll down, we can find the math. You can see that there's
even more for floats because they're a bit more versatile as they
have a decimal point. So that's gonna be
it for this lesson. Just like the Boolean, we will be using
floats and integers a lot more in future lessons just because they're kind
of the core part of doing any math in the engine. So you'll be getting quite familiar with them
in the future.
8. Variables (Names, Text & Strings): Hey everyone. In this lesson we're gonna
be going over the name, string and text variable types. All these variables are
used to store text and each variable type has some limitations and
benefits to using them. First up, we've got the
name variable type. Now, this is used to store texts at the player
doesn't normally see. It's more for referencing
certain things in code. So for example,
when we want to get a bone or sockets location, we would use a name
variable to tell the engine which bone or socket we want
to get information for. So because of that, the name variable
is quite limited. It doesn't need all
of the nodes that strings and texts
variables have access to. So we'll start off by
creating our name variable. So I'm just going to create
a new variable and I'll call this example name. We'll set our variable
type to the name variable. And we'll compile. Once that's compiled,
you can see we've got our
default value here, and this is just a
standard textbooks that we can enter text into. So I can put hello. This is a text variable that
stores that information. Now as you would expect, like our previous variables, we can get and set
this variable as well. So we can drag it in
and get a get node, or we can drag in and
get it a set node. Now the only different
series that are set node has a textbox that we can also manually enter text
into if you wanted to. So we can set hello. And if this node will run, it would sour
example name2 hello. Of course, if we had
another name variable type, we could plug this straight
into our set node to set our example named variable
to a different value. Now, because all of our variable types that we're looking at today are
texts variables. They all store text. They can all be converted
to one another. So if I was to create
a new string variable, so I'll call this
example string. The autosave exited my time. There we go. Example string. We can choose the string type. And if I get my string variable, you can see if I drag out
and connect up to my text, it just gives us this
conversion node and that will take whatever
our example string is, it's texts value and set
it to our example name. And we can do that and
the reverse as well. So if we wanted to, we could set our string using
the example name. And it gives us that conversion node the other way around. String variables are the most flexible of the texts
variable types, they have a lot more
nodes available to them than texts or name
variable type stay. Because of that, it can
be useful to convert say, a name or a text
variable to string, edit that string,
and then convert it back to our name or
text variable type. As we can do a lot more editing encode with our string type. Lastly, we have the
text variable types. So I'm going to create
a new variable. I'm going to call
this example text. And we'll set the type to text and we'll compile so we
get our default value here. You can see like our
previous variables, we get a textbox so we
can add text to you. This is a text variable, for example, we can compile and that's now our starting
value for our text. Now, texts variables are used for the texts that
players tend to see. So if you had a dialog system or a menu system or
anything like that, that the player actually
sees the text values. We tend to use Text
Variables for that. And the reason is because
it can be localized, which is used for converting
text to different languages, which unreal has a
built-in system for. We won't be covering
that in this lesson. But it's important that
when you are building menu systems or any texts
that the player will see, you use a text variable types
so you can have access to that localization system which allows you to have
multiple languages. So texts can be get and
set the same way as we have done with our string
and our name variables. So we can drag this out
and get a get node. And that node, you can see that it's similar to our
name on string. We have a text entry and we can set our node to
another text variable. Or we can use say, a string. We can get our string variable. We can plug that straight into our texts and you
can see that it gives us a different looking
kind of conversion node, but it does essentially
the same thing, whatever Example string is, it will convert that to text, and then we can set
our example text. And the same thing for our name. So if I get the name variable, we can plug that
straight into our text. You can see that we get this convert node
automatically come up that converts our name
text to a text text. And that allows us to set
our example texts variable. Next, I want to take you through some commonly used nodes with these different
variable types. And we'll start with
the string because that has the most amount of
nodes that can be used with it and is generally the more flexible texts type
that you can use encoding. If we drag out one of the more commonly
used ones is append. So if we search for append, we can bring up this node here. Now the append node
allows us to take multiple string inputs and combine them together
for one output. This can be useful if
you want to say add additional text to a string without changing the
original variable. Or if you had multiple
string variables, you can plug them into
append and then it will output those texts values
combined together. So for example, if I set my
example string to hello, and I set the B2B space, this is a test. The output of this
node would be hello. This is a test all
in one string value. And we could use this to maybe set another string if we wanted to or set example
string as well. We can add additional
inputs as well. So if we wanted
to, we could have other variables plugged
into these inputs, and they would all be combined
together into one output. Another node that
can be used with strings is the contains node. So if we drag out and
search for contains, we can get the string, we can get contains. And this will search
our substring. So it will check is the
substring in this text. So if I was to say hello, it would search this string
to see if the word hello is contained in it and then
return a true or false value. So because our example
string is set to hello, this would return true. Then we've got a
couple of options. So we've got use case. This means is it case-sensitive? So for example, if I was to change our age to a lowercase h, The hello in our string
has an uppercase. So this would actually return
false because it doesn't exactly match our
lowercase hello. We've got search from n, which basically just means
that it will search from the end of the string to the beginning instead of
beginning to the end. Another node we can use
is the replaced note. So if I drag out from my
string search for replace, we can create the replace node. And this allows us
to set texts that we want to replace and what
we want to replace it with. So if I select my example
string here and I add, say the word test, I set the Fromm to test
and the two to unreal. It will replace all of the
test words with Unreal. And then here we can just
set whether or not it's case sensitive and that will
output the new variable. So we can actually set that
to our example string. Okay, I take node just
so we can sit and gain. Plug that into our set node, will create a print string and connect that
up to the output. So now when we hit play, we'll see our example
string say hello and rail instead of hello test, which is what it's
currently set to. Now the last node we're going to look at is the equals note. So if we delete our
replaced noted drag out from the string and
we can search for equals. And we want, well, we've got a few
different options here. We've got exactly equal. So this is a case-sensitive
equals node. So if we create that and see that it's got three equal signs. And this will check, is both
the inputs exactly the same, including upper and
lowercase letters? If it is, it will return
true if not false. Or we can use the equals
case insensitive. So this will return true if
the text values are the same, even if they have different
upper and lowercase values. Then lastly, we
have the not equal. So this will do the opposite. This will return true
if the text inputs are different and it returns false if the text inputs are the same. So we're going to move on
to our name variable now, if you want to find any of the other string
functions are available, just drag out from a string
variable, search for string. And you'll be able to find
all of the string functions under the string category
you can see here. So we're just going to delete
this code now and bring in an example name
get node like that. Now, our name variable is a lot more restricted than
the string notes. There's only a few
notes that can actually be used to that. If we drag out, we can
search for the equals. This gives us the
original equals node. You may notice this
from our integer video, but we can't change the inputs. So if I right-click, you can see there's no convert options. This node, we're
basically just take into named variables and
check if they're the same and return a
true or false value. We can also create a
switch on NameNode. So if we delete this node and we drag out and search for switch, we can create a
switch on namenode. Now this works similarly to the integer switch that we created in our previous lessons. We can add new output pins. And depending on what our
input variable is set to, we can run a
different output pin. So you can see over
in the Details panel we've got pin names. So I can change these
names to say hello. And we'll change the
second one to test. Now, if our example
name is set to, if we just change it to hello, when this node runs, our hello new pen would run. And if it was set to test, our test pin would run. And then if it was set to
something completely different, just random letters than our default pen
would run instead. So you can control
which code is being run by a name variable
using one of these, this node actually also works
with our string as well. So if I just quickly
drag out a string, we can do a switch
on string as well. That works exactly the same way. We can create new inputs,
change their names, and they will run
depending on what our string input is set to. Lastly, we'll move on
to our text variable. So I'm just going to delete
these and we'll drag in a gap for our example text, like our string node, the texts can use
an equals nodes. So if we search for equals in C, we've got the same nodes
that we had for our string. We've got exactly equal, which means if both inputs
have to be exactly the same, texts values for
it to return true. We've got the case insensitive, so it just has to be
the same text values. It doesn't matter
if they're upper or lowercase and then return true. And then we've got
the not equals, meaning both inputs have to be different for the
snow to return true. Now, our text node
cannot do switches. So if I drag out and
search for switch, you can see there's
no switch on text, so that's a limitation. It also can't do
things like append. You can see those options aren't there like
our strings is. But we can use
format, format text, which is a bit more of an advanced version
of the append node. Now, the format text node is really helpful for
things like creating item descriptions or anywhere where you're going
to have different inputs into your text. So what I mean by that
is if we add a format, so this item's name is now we might be able to
hover over our mouse over different items and we want this name of the item to change, but we don't want this
original texts to change. What we can do is add
these two brackets here, and I'll zoom in so you
can see the bracket type. Now, whatever name we put
in between these brackets, we'll add us a new pen. I'm going to call this
item name. Hit Enter. You can see we've now
got an item name input, and this is a wildcard
so we can add, we can plug in a text
if we want to do all, we can add an integer or a string or a name,
whatever you prefer. And whatever we input, it will output this item's
name is and then the input. So as an example, if I add a tick will drag
out and do print string. We can just connect the
result to our print string. And I will plug my example
texts into item name, and we'll change the example
text to Apple like that. So now when we hit play, we will see this
item's name is Apple. See this item's name is apple. And we can extend
this even further. So we could put this item does, and we'll do the brackets again, damage type and hit Enter and
now create another input. And we could say use our string. We can drag that in, connect up to damage type. And we can put fire. And we'll add in
damage after here. So now I will say this
item's name is Apple and the item does fire damage, hit play, and you'll see that it's printing
out correctly. If we wanted to, we could set these variables
using other codes so that every time we hover over a different
item, for example, the item name changes to the correct name and
the damage type changes to say the cracks damage types. So if I change this twice, you can see now
when we hit play, it says ice damage
instead of phi damage. That's gonna be it
for this lesson. Hopefully you now
have an idea of what each of these variables
would be useful. Just to go over it again, texts variables are
the ones that we use to actually display
texts to the player. That's where we're
going to store things like an item's name, descriptions, things like that. Then we've got strings
that are useful for editing in our code. But we don't tend to display that to the player because they can't be used for localization. And then we've got the name
variable that's more used purely encode for referencing
things like bone names, sockets, DataTable
rows, things like that.
9. Variables (Vectors, Rotators & Transforms): Hey everyone. In this lesson we're gonna
be going over vectors, rotators and transform
variable types. Vectors or a variable used to
define objects, locations. It's made up of free
floats called x, y, and z. If I select one of my
cubes here in the level, you can see in the
Details panel we have a location
and that has an X, Y, and Z location. And as I move the cube around, you can see that
those values change depending on which
axis I move the cube M. Rotators are similar to vectors in that they're
made up of free floats. They have X, Y, and Z. They also have secondary names. So if we have our cube selected, you can see x is rho, y is pitch, and z is your. If I press E with
my cube selected, you can see that we can rotate our cube and those
values begin to change depending on the axis that we're rotating our cube. Then lastly, we
have transformed. Now this location and
rotation and scale variables are all actually part of one variable
called a transform. Transform is used to define
an object's location, rotation, and scale
in the world. Now, the scale is actually just another vector that's made up of three floats as the same names as
our location vector. We've got x, y, and z. And one means that the AXA
is its normal standard size. If we increase this to say two, it'll be twice its
standard size, as you can see here
with our cube. So now we're going to
take a look at how we can use and change these
values inside a blueprint. So we'll open up our
third-person character here. And just to start with, we're going to create
a new variable and we're going to
call it vector. And we'll change our
variable type to a vector. And we'll drag that in and get the variable also
dragging a set as well. So you can see what
that looks like. Now. Our get node looks
pretty much the same as our previous variables, but our set now
has three inputs, and this allows us to set
a value for x, y, and z. You may have noticed this is a decimal point number because these are just individual
floats that we can set. We can set these in a
few different ways. We can connect another
vector up to this input, and that will just
set our vector to whichever variable
we plugged into it. We can set these
individually manually. So I could set these to say 123. Or we can actually drag
out and search for meat vector, the vector node. And that actually
gives us this node, which allows us to plug in a float variable
fee any of these x, y, and z values. Another way we can set this
variable is if we delete our make note here and
right-click the vector pen, we can split struct pen, and that actually allows
us to set the floats directly onto the set node. So we don't have to have
that make vector node. And if we want to recombine these back into
the original pen, we can just right-click
select recombined Struct Pin. And that will reset
our SAT node. Now with our vector,
if we select it, you can see we need to
recompile our blueprints, so we'll just do that
quickly and again, in our default values, we can set an x, y, and z value, and these will be our starting values
for this variable. Next, I'm just going
to take you through some common nodes
used with vectors. So the first one is R equals. If we drag out and
search for equals, then we've got equal exactly. This is a node that basically checks both these vectors that are input into this node
exactly the same as the x, y, and z values are the same. If it is, it will try and treat. We also have a nearly equal. So if we use the
equals note here, you can see that that gives us two vector inputs and
then a float input. And what this does is we
can plug two vectors, n. And we can say, we can give
it an error tolerance. So we can set this to say one. And this will return
true if the x, y, and z values are within
one of each of each other. We can also use all of the standard maths nodes with our vectors so we can drag out, we can use the Add
Node that gives us the ability to add two vectors together and return the result. We can use the minus node
or the subtract node. That does the exact same thing, but it subtracts the two vectors from each other and
returns the output. We've got the Multiply node, so we can search for multiply, and that will give us
the most ply node. This will multiply the x
by dx of the top value. The y value is y and the z by the top value C.
And I'll put the answer. Of course we also have divide, so we can search for divide. And that operates the same way. Divides the top value but the bottom and gives
us the answer. Now, like our
previous maps nodes, we can change some
of these inputs. So for example, I
can right-click the bottom input here
and convert the pin. We can change this to other math variables
so integers floats. For example, if we wanted to say minus a certain float
from all our x, y, and z values and our vector, we could change it to
a float and do that. We can do the exact same thing
of our Add Node as well. So maybe we have an integer
this time we wanted to add an integer value to all
our x, y, and z values. We can do that as well. The next stage we're
going to look at is called the lap nodes. So we're just going to
delete these notes here. We'll drag out from my
vector and search for lap and create that node. And this allows us to take two vectors and give
a vector output. And this alpha value is a float. And this is essentially the value between
these that we want. So for example, if
we had a value and a and a value and B,
and we set this to 0.5. The output location
would be exactly between these two
input locations. Next, we're going to take
a look at the break node. Now if you remember
from our set node, we can drag out and
search for make factor. We can also do the same with a vector get node we can drag out and we can search for break. And we can break that
vector now into its x, y, and z float values. We can also right-click
our vector, get node and select
Split Struct Pin. And that gives us direct access
to those values as well. And if we want to recombine it, we just right-click again and select recombine structs pen. Now we're going to
actually use the vector to start effecting an
object in the world. So you can get used
to doing that. To start with, we're going
to create a new access. So we'll go to the
content browser, right-click and create
a blueprint class. Then select axon. And we'll call this cube, open up our queue blueprint, and we'll add a new
component called cube. That's just gonna give
us a cube component, will compile and save this, and then go back to the
ThirdPersonCharacter Blueprint. And we'll right-click and
search for left mouse button. Then from press will
drag out and search for spawn actor from class. And this is going to
create a new actor in our level whenever
we left mouse button. And we're going to
set the class to cube because we want
to spawn our cube. And we'll drag out
from spawn transform and search for make transform. This works similarly to
the make vector node. It just allows us to instead
make a transform variable. So you can see we've got
our vector for location or rotator for rotation and then our second vector for scale. And we're gonna be
using the location to choose where we want
our cubed spawn. I want my cube to spawn just
above my character's head. So I'm going to use the get actor location
load will create that. You can see the output is a vector and the input
is an actor objects. And currently it just says south because nothing is
plugged into it. So we're going to be getting our third-person characters
act to location. If we drag out and we
want to use an add notes. So I'm gonna do add. We're just delete our vector
variable here for now. Now I want it to spawn
slightly above my character, because if I plug this
straight into location than a cube is going to spawn
right inside our character, which will mess
up the collision. So we're going to
take the output, plug that into location, and will increase
this by say, 150. So it's nicely above
our character. So now we can compile
and hit play. When I left mouse button, you can see a cube as
spawn just above my head. If I move over another
cube or spawn, they'll keep doing that as
I move around the level. Now if I wanted the cube
to follow me around, we can do that as well. So if I exit out and go back to our ThirdPersonCharacter
Blueprint. So to have our cube follow us, we need to make a few changes
to our code to start with, we're going to drag out
from the return value here, and we're going to select
Promote to Variable. What this will do is create
a new variable that's the same type as our pin
that we're dragging from. So will promote the variable. This will create a
cube variable type that we'll call cube. And this is an act of reference variable which we will be
covering in a later lesson. But essentially, this
just allows us to tell our new cube what
we want to do with it. Then we're gonna get
our new cubed variable. We're going to drag out
and we're gonna do is valid and create
an is valid node. The bottom one here, we'll make a bit more space
and we're going to connect this up to the pressed. And then the is not valid up
to our spawn out to cube. And what this does
is basically check, has r cube Admin created before. If it's not been created before, so it's not valid, will run, and that will
allow us to create a cube. And if our cube
has been created, then it's valid, will run, which won't do anything. So that just stops us
creating more than one cube. Then we'll create a tick node. So we'll do event tick. And we'll actually copy
these two nodes as well. And we'll connect the
execute to the authentic. And then we'll drag out
from our cube and we're going to use the set actor. Location node. This allows us to change our cubes location depending on our new input. We're using. This is valid just to make
sure we don't get any errors. Because if we try and
set our cubes location without our cube having been spawned yet, we'll
get some errors. So we use the is valid,
stop those errors. And we're going to
set its new location to the same as our
spawn locations. So I'll just move this
a little bit higher. And we'll copy and
paste these nodes. And we'll connect this
to our new location. So now, just to run
through this code, every frame cube will
set its location to our current characters
location plus 150 and height. And we can play this now. If I hit play and
then left mouse click and see we've got our
cube as following me around. If I spam left mouse button, it's not actually creating
any more cubes as well. Next, we're gonna
be taking a look at the rotator variable. So we'll exit out
of play and head back to our
ThirdPersonCharacter. Will keep this code here
for now because we can use it to do some things
with the rotator. Once I've shown you some of the commonly used nodes
with the rotator variable. So we'll create a
rotator variable just the same way
as we have before. Create a new variable. We'll call this Rotate tool. And we'll set its type
to the rotator type. Then we'll compile, shore
up our default value. You can see here it's very
similar to our vector. We've got an X, Y, and Z, and these
are float values. We can get our rotator by
dragging and selecting get. And we can sow rotator
by doing the same with the set option in C. Again, like our vector, it
gives us an x, y, and z. We can drag out and
search, make rotator. And we can select the
rotate option here. And that gives us
those variables that we can use to
then set our rotator. Or if we want to, we can right-click and select Split Struct Pin to get
access to those directly. So we can use a float to set any one of
these individually. Like our vector, we can also
drag out from our rotator, get node and search
for break rotator. And that gives us our x, y, and z values as floats if we needed to access
just one of those. Now, unlike the vector, we can't use a normal maps now. So if our rotator variable, there's custom nodes that
are used just for this. So if we drag out and
we search for combined, you can see we've got a
combined rotators node, and this essentially just
combines a with the B values. So you could use this
to minus or plus values to your rotator and then it will
give you an output. We do also have access to
the lab for our rotator. So if we drag out
and search for LAP, see we've got lip rotator
and this works the same as our love
for our vector did. We cannot have two inputs
to rotate or inputs. And we can set an alpha, and this is a value
between 011 would be the output value would just be the b value and 0
would be the a value, and then 0.5 would be the value
between these two values. Next we have the gap
rotation x vector node. So we'll delete that node
here and we'll search for rotation x vector. And this is important
because it allows us to get the forward direction in a
vector variable of an actor. So x is the forward
vector for most actors. So if we go to our level here, I just drag in a third
person template. You can see that
x, which is red. You can see red is
x is our forward. So this allows us to get the forward direction for
our character at any time, for us to rotate it like this, I'll forward direction
would now be over here. But you can see the world
x-direction is still this way. We can use this node
to get the direction that something is facing
depending on its rotation. We can show you
this in an example. If we go to our third
person template and we're going to edit
some of this code so that our cube actually spawns forward in a direction of our
characters facing. So to do that, we're gonna
get our characters rotation. So we'll do get rotation, will find the rotation. There we go, get
active rotation. This gives us the current
rotation of our character. I'm going to drag
out and we're gonna do get rotation x vector. And now we're going
to multiply this. So we'll drag out
from the vector and we'll do the Multiply node. And we're going to
change the input here to a float because we want to
multiply it by a float value. And here we're going
to set how far ahead of our character
we want r cubed spawn, and this is in centimeters. So if I set this to 500, then we're going to plus this two are actors
current location. So we're basically saying 500 centimeters in front of our characters
current location. We want to spawn this cube. So we'll drag out from our plus note here and we'll
do another plus node. And we'll add our
times value here. Set this to the location. I'm going to just reuse
this and plug this into our new location up here so
that when we spawn our queue, but it follows us around, that location, will
compile and save this. And that will play and game. So if I hit play, you
can see I can run around and if I click inside the cube is
spawned over there. And if I rotate the character, you can see that the
cube is actually updating its location
ahead of me. Now I haven't set it up to
use the camera's rotation. So that's why when I look about, it doesn't change the cube. But instead when I
rotate the character, you can see that the
cube is now updating, is five meters ahead of us, but it's still keeping
the characters location, so it's still following
along with us. If I was to change that
500 value to say 200, than the cube would be closer to us because it's
only two hundred, two hundred centimeters
in front of us. So now you can see it's two meters ahead of
us and it's still updates in the forward
direction of our character. So now if we go back to our ThirdPersonCharacter
Blueprint, there are a couple of
other notes we can use with our rotator variable. So like we've got the
set actor location note, we've also got the
set actor rotation, node rotation, which
does the same thing, but instead sets are rotation. And we can actually do some rotating if we
want with our cube. So if we drag out from
our cube and do set factor rotation at that, and say every frame, every frame we want to rotate
our cube a little bit. So we need to get as current
rotation and then add to it. So we'll drag out and
do get to rotation. We'll do combine rotators. Would just plug this
in here and we'll say, let's increase this by one and see how this
looks. So hit Play. If I left mouse, you'll
see that it's now rotating in that direction. If we were to change the values on our
combined rotator node, we can add a one
in the y as well, and we'll see it do a
different rotation. Next, we're going to cover
the transform variable type. Now, we've already covered a
little bit in this lesson, but essentially a transform is just a variable that's made up of a vector for the location, a rotator for rotation, and then another vector
for our actors scale. And we can access that
variable the same way we have been our location
and rotation. So if we head back to the ThirdPersonCharacter
Blueprint now, we can create a new variable. We'll call this trans form. And we'll set its
type to transform. Now, similarly to
the other variables, we can get it and we can center. Now you can see it doesn't have the x y options because there's multiple inputs that are transform needs
from our set node. If we drag out, we can
do make transform. And this gives us access
to set its location, rotation and its scale. And this is a vector, a vector and our rotator
here in the middle. And we can set these
manually if you want to, on this node. Or we can plug in vectors and rotators like we
have done before. We can also split this node as well like we've
done with the other ones. So if we right-click
the pin here, we can do Split Struct
Pin that gives us access to the location,
scale and rotation. And we can actually split this
further if we want to say, I just wanted to
set this transform to X1 and I had a
float variable. I could actually
split this pen again. And you can see I can now set the x float value for our
location all on this one node. And then if I want
to recombine it, recombine and then
recombine again, and it's back to normal. We can do the opposite with our transform get
node, we can drag out, you can search for a
break break transform and we can access our location
and rotation and scale. We can also split
this as well so we can right-click and
do Split Struct Pin. And that gives us access
to those as well. Now we can set an
actor's transforms. So if we go back down to
our code from earlier, you can see we've been saying the actor location and
active rotation separately, but we could actually
drag out and use the set actor transform node. And that would give us
access to its transform, which of course is made up of
its location and rotation. So we could do make
new transform. We can actually be setting
these without these two nodes. So if I delete these two, we could actually be
doing that with one node. So I'll plug this
into our is valid. Using a make node, we can just take our location from where we are
getting it from before. So down here. Then our rotation,
we put that into rotation and we'll
leave scale as one. But if we wanted to, we
could adjust that as well. Now, if we hit play, we can actually
see that it still works exactly the same
as it did before. We're just using
that one node now instead of the two
separate ones. Now, the last thing
I wanted to cover in this lesson is the
difference between local and world
transforms will exhale play for now and we'll head to the ThirdPersonCharacter
Blueprint and inherent. We'll go to the viewport. Now in the viewport we
can add a component, so I'm just going to add a cube. So that's Saturday cube now
into our blueprint viewport. And we can see we've
got a location here and currently this
is reading zeros are 0. That's because our cubes
current local location. Is 0, the center
of our character. If I was to move it forward, you can see that it's
increasing in the x. And now if I can pull
this and place this into, place our character
into the level, you can see our characters
now at this location. But if I select my
cube component, you can see that it's giving us a different value
from our actor. Now, that's because this
value is a local location. So it's currently
a 170 centimeters from the center
of our character. But when we select
our character, so when we select
the full actor, it gives us our world location, and that's our actors
location in the whole world. Now we can change
both j components, world location and local
location in blueprints. So to do that, I'm going to open up the third-person
character here, which can delete a
lot of this code. So we'll delete all of
the codes connected to the tech and will delete
all this code as well. So we're just left with our
left mouse button of them. So now we're gonna go
to our viewport and we're going to select our
cube that we created. I'm going to reset it to 0, so it's just in the center
of our character here. And then the event
graph, we're going to drag it out from the components. And we're going to tell it to
set its relative location. And we're going to set this
to 0 on the x 0 and the y, and then 150 on the z. Now when we press
left mouse button, it will move it to
this new location. So if we hit Play and see currently it's just in the
center of my character. But if I left-click, it goes
above my character's head. The reason it's done that
is because these zeros, zeros 0 location for my cube is right in the
center of my character. So all I've done is
told it to increase that by a 150 in the z. And now it's above
my character's head. Now if we change this
code to instead of relative location or
set world location, and we'll use the same values. So x is 0, y is 0, and then z is 150. And if we hit Play,
I'm not going to move. I've just clicked
and see my cube. If I press F1 is over
there behind the wall. Now the reason it's doing
that is because that is 0 in the world, but plus 150 centimeters up. Now if I move, you
can actually see the cube moves with
my character style. And that's because the cube
is attached to my character. But we've told it to move
to 00150 in the world. So that's the difference
between setting a local location and
a world location. Now, if I press F
free to go back to our normal lighting mode there and to access the wireframe. You can press F1. If you didn't know that. Butt press F3 and exit. We can get the same result with our set world location as we got with our set
relative location, we just have to do
get actor location. So we get our current
character's world location. We drag out and we'll do plus plus 1 fifth to its
current world location. And we'll set our cube to that. Instead, we're taking
our current actors location in the world, placing 150 and then setting
R cubed to that instead. So we can test this out. Now, if I hit Play,
if I left-click, you can see we've now
got that same result as we did when we use
the relative location, because now we're adding on
our characters wild location. So our cube now stays above
our character's head. So that's it for this lesson. In our next lesson, we'll
be taking a look at ACTA, an object variable types. We've used them a little
bit in this lesson, but we'll be learning
a lot more about those in our next lesson.
10. Variables (Actors & Objects): Hey everyone. In this lesson we're
gonna be taking a look at object reference variables and how they're used in the engine. So I've set up a very
basic example here. We've got a trigger and
we've got some cubes. And when our player
enters the trigger, one of our cubes all move up. And then when the player
leaves the trigger, one of them will moves down. If I hit Play and I've
run into a trigger, you can see the right cube moves up and if I
leave the trigger, it moves back down. Now, this is happening
because our trigger hair has a reference to that cube
that you can see down here. This is an object or an active variable
that set to our cube. And I can actually
change this by picking the pick actor
from Scene button. I can click one of our cubes so I can pick the cube
on the left here. And now when we hit
play and I run over the trigger is now
changing our left cube. And essentially what object references allow
us to do is tell the engine which specific
objects we want to effect. Because all these cubes
are exactly the same. They use our cube class
from our content browser, but each one is an
individual object. We may want to affect one of them without
affecting the others. And object references
allow us to do that. It will take a look into
our trigger blueprint and see how this is working. So I'll just open that up. You can see that we've got
our selected object variable, which is what we're using to control which cube
we want to effect. So you can see this is called selected object and
it's set to our cube. And we've got that
up variable here. It's set to type Actor. We've also got some
code in here which controls what we do to
our selected object. So we've got active
begin overlap, an event actor and overlap. These are some of those events
are built into the engine. So these will run
whenever something overlaps or trigger or stops
overlapping our trigger. Now, you can see both
of these nodes have these overactive pins and
these are object references. They are telling
us exactly which object overlapped or trigger. Now, this is a cost node. We will have a separate
lesson on costs because they are quite important and there's a lot to them. But essentially what this
is doing is it's taking an act of reference
and it's checking, is this actor a
ThirdPersonCharacter? And if it is, then it will allow our code to run an F naught. It will return cost felt. So we're essentially using
this cost node as a check. We're basically saying, if an act to stop begins
opening lapping us, is it a third-person character? If it is, then we can run
the rest of our code. If it's not, then we
don't run our code. And then the rest of our code
is basically just taking our selected object that we are setting in the options here. And we're telling it
to set a new location. So we're just taking its
current location and we're plotting 150 and setting
it to that location. Again, we're doing
exactly the same thing down on the end overlap, but instead we're
minusing a 150 from its current location and then setting it to that new location. Next, I want to explain
what is an actor? An actor is any type of object
that exists in a level. So everything you can see
here is a type of actor. There are lots of
different types of actor, like for example, the
character blueprint here. If I drag that in,
that is an actor, but it's a different type of
actor, say character type. It can do everything
can actor can do, but it also has
additional functionality because it's meant to
be used as a character. Like for example, it can
be controlled by a player. It has a capsule and a
character model as a camera. These are all things
that are built-in to our character blueprint. These are all things that actors by themselves don't have, but our character does
because our character is a specialized type of actor. Now, this is done through a
process called inheritance, which can be a little bit
tricky to understand. So I've created an image here to try and show you
guys what I mean. If I bring this
over, you can see that we've got a new
object at the top. Now, essentially,
every single object in Unreal is a U object. There are very basic type of object and everything
inherits from them. Moving down the chain,
we have actors. Now, actors are what
we've been talking about. They inherit from your objects, meaning they have everything
that you object can do. But then they also have their own additional
functionality that allows them to
exist in a level, have components and be visible. And you can see I've
added the cube and our trigger blueprints that we've been using
for the example. You can see that those
inherit then from our actor. So these are actors that can do everything a
normal actor can do. But because we've added a
code to our trigger and a collision box is now its own type with its own
special functionality. And then the same for our cube. We've added a cube
component to it. So it's now its own type
with its own components. Are characters the same? It just has some
additional steps. So you can see that from
actor a **** is created. Now, a **** is a
more basic version of our character blueprint. It can be controlled
by the player, but it doesn't really have
any of the movement or. For our characters
model to be visible, then we have a
character blueprint which inherits from the ****. So it gets some of
its abilities to be controlled by the player and some of its
movement abilities. And then extends on
that and allows us to have a capsule component
and a character model. Now our character
is still an actor. It's still can do everything an actor can do the same way. A **** is still an actor and can do everything
connected can do. But each one of
these steps just add some additional functionality
to their blueprints. Now all ThirdPersonCharacter
Blueprint would actually be the
next step down from our character because
our ThirdPersonCharacter inherits from the
character blueprint, we've just added some
more functionality to it. We've set a model and we've
changed some of its settings. So now it's its own blueprint. That's a child of the
character blueprint. Now, going back to our example, if we select our trigger, you can see that when I select the drop-down for
our selected object, you can see I can select
any object in the level. Now the reason that
is, is because this is an act or variable type. And that's because everything
in our level is an actor. If we wanted to, we
could change this from cubed to even our sky. And if we select the sky sphere, you can see I can set this to a sky because our
sky is an actor is just a special type of vector with its own settings
and components. Now, if I wanted this to be more specialized and
only give me cubes, for example, we
would have to change the variable type from an actor
to our cube type instead. What we'll do is we'll
set this back to a cube, so I'll just switch so cube. And we'll select our
cube blueprint here. And then we'll open up
our trigger blueprint. And in here, we can select
our selected object. You can see it's currently
set to an actor object type. But if we change this, we can search for cube. For example, we've got
our cube blueprint. We can select object reference. And when we change
a variable type, it will give us this
warning just telling us that we're changing a type. It may cause some problems. We're going to select Change
variable type anyway. We'll close this search
window and we will compile. So now when we select our trigger in the level
and we click the Drop-down, you can see it's only
showing me cubes now, that's because we've set our selected object variable
type to the cube type. You may be wondering,
why would we ever use the cube type when we can just use the actor type and
select any actor we want. Well, you might have special
code or variables in our cube that we want to get access to in other blueprints. So we'll open up the cube and I'm just going to
create a new variable. And it's gonna be a Boolean. And I'm just going
to call it example. Now we've created this
variable in our cube. It's a variable unique to our queue blueprint and only the cube blueprints
have this variable. So we'll go back to
our trigger blueprint. Now, because our selected
object variable is a cube, if I drag it out and I searched, for example, you can see I can now access that variable
using our selected object. And this would give
us whether or not our example variable is true or false on the cube that we
have selected in the level. Now if we went back to
our trigger and change the variable type for a selected object
from cube to actor. Now if we compile, you can
see the connections gone red. Now, that's because
if we drag out from our selected object and
search, for example, again, we can no longer
find that variable because that variable only
exists in our Coupa blueprint, not in the actor. And because this is
an act of reference, it won't find variables that
exist only in our cube. It will only find code and variables that
exist in the actor. Now there are ways that
we can access our cubes, variables, and functions from
an act of variable type. But that would require casting, which we're going to go
into in a future lesson. For now, I just want to cover some more commonly used nodes
with object variable types. We've already been
using quite a few of these nodes in previous
lessons, in this lesson. So we've got things like
the SAT ACT or location, SAT ACT or rotation that and
set actor transform nodes. We've been getting
our actor location with the great actor
location node. There's also the
get's actor rotation, which does the same thing, but it gets our
actors rotation in the world and returns a
rotator variable type. Next we have the
Destroy Actor node. So if we delete our rotate
here and drag out and search for Destroy Actor. Now, when this node is run, our actor will be destroyed. And we can use this with any
apps or type in our level, and it will remove that
actor from the level. Now another commonly used
node is the is valid node. So if we take our, if we delete our get
actor, note him. And I'm going to drag out
and search for is valid. In C, we've got two options. We're going to use the
bottom one for now. This gives us a
note that checks is our selected object to
actually set to anything. So if we go to the
showcase level here currently are selected
objects, sector or cube. But if I clear this
is now set to none. None of the cubes
will be affected when our character and over up. And if we hit Play
and I run into the cube and then run
out and I exit Play. You can see that I've
got some errors now. Now that's because our trigger
code is basically telling our selected object
which isn't set to anything to change its location. And that's what's
giving us these arrows. So what the is valid
node allows us to do is check is are selected object
actually set to something? If it is, then
we'll run is valid. And if not, we'll
run is not valid. So if we take these nodes now, I'll just copy and paste them. Connect them up to
the bottom here. And we'll hit play. Now when we run into the box, even though we've got
nothing selected, we won't get any errors. Now, as you can see,
because that is valid, node is now stopping
the code from running and giving us arrows. The other is valid node
works in the same way. So if we search for
it, it's valid. You can see this
is a function and it basically does
exactly the same thing. It just gives us a Boolean, so true or false value instead of this node
with the outputs. So we could use this with
a branch node for example. Lastly, I just want
to cover how we can set object variables. So we can just drag them
into our event graph, select the option here. And using the set node we can drag out from our object input. And because we're
using an actor node, we can connect this up to any
other actor variable pen. So you can see we can plug
this into the other actor pin here or the output pin on
our car snow just fine. But if we create another type of objects,
say a character. So I'll just call
this character, and I will set its type
to character as well. So character and then
object reference. And then we'll
compile. If we drag in our character and
create a set node. You can see if I drag
out from the input, I can't plug it in to the output of our
actor begin overlap. And that's because this
is an actor output. Now all actors are
not characters. So our actor can't connect to the input of a
character set node. But if we drag out
from our input, you can see I can plug this into our third person cost node. Again, we will be doing
separate lesson on costs. But essentially, this node is taking an actor input
and it's checking, is this a character? If it is, then we can output
a character variable type. And we can use this then
to set our character variable because both of these pins are now
a character type. Now that's it for this lesson. Hopefully you now have a
slightly better understanding of how object variables
work in the engine.
11. Variables (Arrays & Loops): Hey everyone. In this lesson we're going
to be taking a look at array variables and loops. So to start with, we're going
to create a new variable. So we'll just do that by clicking the new
variable button. And I'm going to call
this example name array. We'll set the type to name
over in the Details panel, in the variable type, you can see we've got this
little button over here. And here is where we can set
what type of variable is. So currently it's
a single variable. That's what we've been
working with so far. But next we're going to
select the array option. So do that and
we'll hit Compile. And you can see that it's
got a different icon now in the type that
indicates that it's an array, you can see that my
default value as now this different
looking option here. Now an array is basically a way of having
one variable that can store multiple values
of that same variable type. Our name variable
array here can store multiple named values just in one variable in our
default values. If I click this little
plus a few times in C, That's given me
free entries here. Now, on the right-hand
side we have our variable. So because this has
a name variable, this is a name value. So I can enter
names in here so I can put it say James, bill. And well, for example, now these actors normal
named variables. If I was to quickly create another variable which
I'll just do now, I'll call this
example float array. I'm going to change the
type here to float. And it's already
set up as an array. But if yours isn't, you can just click the array option here. You see it now I've got
a float and it's got that same icon to
indicate it's an array. And when I compile in C, that looks the same here
and my default value, but if I click the Plus, you can see that now on
the right-hand side, instead of the names, we have float values instead. Because this is an array of floats instead of
an array of names. And on the left-hand
side you can see that we've got
these index values. Now this is essentially how we can access these variables, which we'll be using later on. But basically these are the row that this
variable is stored on. So for example, or James, name value is stored at index 0 or Bill value is
stored at index one, and I will value is
stored at index two. Now we can move around
these values using this little indicator on the side here that allows
us to reshuffle these. So I can move, say
well to number two. Number one, you can do that with other variable
types as well. So if I just set this to 12
and see if I drag those, I can reorder them. I want to remove any of these. I can click the little
down arrow, select Delete. I can also duplicate them. Or if I click the little
trash can here you can see it just deletes
all your entries. And that's just
the basic controls for setting your default
values for an array. Next, I want to show
you how we can actually access these variables
in our code. So if I drag in my example
name array and I can just select the node like we usually do with
our variables. You can see that I've got a
different looking variable. Now, I can't drag
out and use this as a normal name variable because
right now this output, any one of our values. To get one of those values
we're going to drag out, I'm going to search for GET. We're going to use gets a copy. And that gives us
this node here. Now as you can see,
we've got an input for an integer and an output
for a normal name variable. And if I drag out from this, I could use any of my
normal name variable nodes. So I could do for
example, the equals node. You can see that it gives me the equals note that
we've looked at before. Just like a normal
name variable. The reason that is is because
this essentially does. It takes our array, gets the index 0 and
then outputs its value. So for example, if I
was to run these nodes, the output of our
get node would be, well, because
that's our index 0. If I was to change
this to say too, the output of this node
would now be bell. The same thing works
with our float array. So if I get my
example float array, and I drag out from that
and I search for or get in C, gets a copy. And you can see we've got
this green version now. We've got an input for our index and we've got an output which is just a normal
float value that we can use a normal float value. So if I do say Add Node, you see I can use an add
know just fine with that, because this is now a single variable instead of an array. And this is the same for
all types of arrays. So we could create an
array of transforms, rotators, vectors, integers, and the process
would be exactly the same. We could set our default values. We could use the get node
and then we just add an index that we want to access, and it will output a
normal single version of the arrays type. It. Now I'm just going to
go through a few of the commonly used
nodes of our array. So we've used the gap note here, but there's also remove nodes. So if I drag out from my name example where
and I search for remove, we can use remove index. And essentially
when this is run, it will remove whatever
index we input here. So currently this is 0. So if we were to run this node, our index at 0, which is currently
well would be removed. Now, something to
keep in mind with erasers when you
remove an index. So if we were to remove
index 0, I can do this. Now. You can see that all of the other indexes move up one. So now James is at 0
and Bill is at one, whereas previously they were. James was one and Bill was two. So this node is
useful when we know which index we want to remove, but it's also another
remove note that we can use if we drag out and
we search for remove, we can do remove item. Now this allows us to tell it, give us a name value and have it removed that value if
it exists in our array. So for example, if I wanted to remove bill from our array, but maybe I didn't know
what index bill was app. I could just have
Bill be the input. Then this node would
check our array, check for the bill value. And if that bill value
is in the array, it would then remove that value. And the output would
just basically be true if the value was removed and false if it couldn't find that value in the array. And those are exactly the
same for our float notes. If I quickly show you, we can do remove index and you can see that
works exactly the same, allows us to remove an entry
from our array output index. Or we could do remove item. And that gives us
a float input to search our array for
and then remove. Now we're going to
look at how we can add values to our arrays
using our code. So we'll remove
this node for now. We will drag out from
our example name, array will search for Add. Now, there's a couple
of options here. We'll choose the top 1 first. Now, the Add Node
essentially just adds the value that we set
here to our array. Now because this
is a name array, this value as a name. But if I was to drag out from my float array here
and search for ad, you can see that that value
is now a float because we're adding a float value
to a float array. This ad note will
essentially add our value at the first
available index. So in our name array, that would be index two
because 01 are taken. So if we were to say
put this to Bob, it would add a bog
value to index two. And it would output that index using this integer
pen on the output. Now we've got the other
ad note, the ADD unique. And this works similarly, but what this will
do is it first checks our array to see if it has or if it already has an
entry for the value we set. So if we add Bob again, when this node is run, it would first check our array. It would see that bulb is not a value that it currently has. It would add it at the
first available Windex, just like our normal add node, then it would output that index using the integer pen hit. If Bob was already in our array, it wouldn't add a
new bulb value, whereas the Add Node would
just add a second bulb value. Now, next we might
want to be able to change a value instead of
adding or removing one. Say we wanted to
change index one from Bill to Bob for example. Well to do that we
would use a set M node. So if we drag out
and we will set L, You can see set array. And that allows us
to specify an index that we want to change and the value we want
to change it to. So if I was wanting
to change, say Bill, I could set this index to one
because bills in index one. And I can set the new value. So Bob for example. So now when this node is run, it would change
index one's value. So the bill indexer to Bob. And you can see that we've got
a size to fit option here. Now this basically
creates new entries if we're trying to set an index that isn't currently exist yet. So for example, if I was
to set this to say four, we only have 01, so we only have two entries. What this would do if
it was run would create a index 23 and then a four. And it would set
index four to Bob. But the two indexes it created to get to number four would
just be empty values. Now, there's a couple of other important notes that
we can use with arrays. So we can drag out from
our array and search for contains and use
the contains item. And this allows us to just
check does our array contains a particular value if it does return true and if
not return false. So if we were to set
this to say Bob, it would check our array. Does it currently
contain the value Bob? It doesn't. So R contains node
would return false. But if it did
contain that value, if we were to add it,
when this node was run, it would return true. We can use the find node. So if we drag out and search
for find, find item Node, you can see here we
can enter a value and then it will search
our array for us. And if it does, if that value does
exist in our array, it will give us the index that that value is currently up. For example, if I was
to set this to bill, it would search our array for
us when this node is run, and it would return
that bill is at index one and that value here, the integer value would be one. Another useful node that can be used with arrays
is the clear node. So if we drag out and
search for clear. This when it's run, will completely
kill it or array. So it'll be essentially emptying our array of
all of its entries. So those are some of the more commonly used nodes with arrays. But if you do want to find
any of the other nodes, you can drag out and
search for array. You can find lots of different nodes here
that will allow you to change and get values from
your array variables. One other note that you might find useful as the
length for node. So if we drag out and
search for length, you can see we've got
a node called length, and this will just count
how many entries we have in our array and output
how many we have. So if I was to add, say, three length node would be free because we have three
entries in our array. Now we're going to
move on to loops. So I'm just going to delete
these nodes for now, and we'll just start
with our name array. So if I drag out and search for loop in C that we've
got for each loop that, that's what we're gonna be taking a look out
for the moment. So we'll create that. Now essentially how
this node works is it takes in and execute. And we'll run the loop body, however many entries
we have in our array. So currently we have free. So our loop body would
run three times. And the way I can
show you this as if we drag out and we
search for print string. And I'll add a big
game play here. Now we have three entries in our name array at the moment. So when we hit play, we will see Hello
print three times. So hit Play, you can see
a lowest run three times. If we head back to
our code and you see that we also
have a complete pen. So once this loop body
has finished running the number of times that we
have values in our array. It will then run
the complete pen so I can add another
print string here. Let me just set
this to say Done. And now what we'd see
Hello print three times and then dumped
would run like that. Now, if we x out of play and head back to our
character blueprint, we've also got an array
element and an array index. Now, these will be
the values of from our array that our loop
body will be running for. So for example, the
first time this runs, the first time I loop
body ones, sorry, the index will be 0 and the array element will
be whatever our value is. So currently these
are all set to none. But if I was to
quickly replace these, I'll just say this
is Bill Bob james. Now, the first time I loop
body would run the value, the array element value would be bill and the array
index would be 0. And then the second time
that rare element would be Bob and the array index
would be one, and so on. Now, what basically
decides when the loop body is run is when it hits a node that doesn't
have an output. So for us that's
just going to print string whatever
value we put here. And then that loop body is done and it will move
on to the next one. Now if it's on the
last loop body, so if it was looping, say for index to the
array element was James, it would hit the end of this C. There's no more nodes to run. And because we're
at the last index, it will then run completed, which is now are
done print screen. So if I plug in
the array element here into our print string, and I'll move these nodes. If we compile and hit play, we should see our names that we've got entertainer
print out on the screen. So if we do that in C that those are printing
out and then we have the W1 value being printed
once the arrays complete. So that's the basics of
how a loop node works, but we do have a
few other types. So if we head back to
our character now and we'll delete this for each loop. We'll drag out and we'll
search for loop again. Now we're going to try the
for-each loop with break. Now this works very
similar to the last node, but it gives us an extra input that we can see
here called break. And that allows us to stop our loop body running
at a particular point. So for example, if we
wanted to run our loop body until we got to the bob Name and then we wanted to
cancel our loop body. We could do that. So if we make a little
bit more space here, we can drag out from our array element to an equal snowed. We could say if our
array element is equal to, I think it was Bob. Bob will say Bob. We want to check a branch node. And we want to cancel while
loop if the value is Bob. So we can do that. We can drag from
True and connect that up to the break input here. And if we double-click
on the white line, we can create these
little nodes that help us organize our code
a little bit better. So I'll just do that like this. So now what will happen
is when our loop runs, will check is the
array element Bob. If it is, then we want to
stop our loop running. So what will this cause us to do is run Bill and Bob
will print on a string. But James won't, because we stopped our loop and completed
we'll have run instead. We can try this out. I can hit Play. You can see Bill and Bob are
running and then it runs done because our james value
isn't being run anymore. If we were to change this
name to say Bill, now, we would expect it to only run the bill name
because once it gets to bill, it would cancel our loop. So we can try this now. And you see Bill,
and then it's just canceling our loop
and done is being run instead of the rest
of our loop completing. We could also do this
with our index if we drag out from our index
and we do equals, instead of using the values, we can just use
the index instead. So say I wanted to stop our loop index
one, I can do that. I could just set
this to one, plug this into our brunch and
compile and hit Play. You can see we get
that same result Bill and Bob are printing. And then the loops
finishing because we've canceled the loop and then
complete it as being wrong. Now, there's one
other loop type that we can take a look at. So I'm just going to
delete these texts. We don't need those anymore. But if we drag out, we can
search for loop again. And there's the
reverse for each loop. And this works the same as the first loop node
we worked out. But instead of looping from
the beginning to the end, it would loop from the end to the beginning and everything else is the same with this node. There are also loop nodes
that don't use an array. So if we delete this for now and I just
searched for loop, I'll scroll down and you'll
see we've got four loop. Now if I click this, you see that instead
of an array input, we've got a first index
and the last index. This basically just
tells a loop how many times is it going to run? So if I was to leave
our first index at 0, but set the last index to say for this loop would run five times because it
would run once for 0 and then again until
it gets up to four. And as it ran through
each loop body, the index would increase by one. We also have that same node but with a break
if we wanted that, we could do a
for-loop with break. And that again works
similarly to our break node. It's just that instead
of an array input, we can set again an index and the last index so far
as to set this to 04, it would run five times. But during our loop body, we could cancel this
loop by running the break input like we just did with the
loop with our array. Lastly, I just wanted to
show you how we can set a race so we can set
them like normal values. So if we drag in, we can choose the set
example name array. You can see that just gives us a normal set node and
we can set this to be a number arrays values so far as to quickly create
another name array. And we set this to name and
change its type to array. We could take that and
we can plug that into our example name array just like we can with
normal variables. And this would just take
our current, or sorry, It would take our name
arrays values and it would set them to the
example name array. So it would completely wipe
our name array and then set the values to exactly
the same as our name array. This is the same for our
float array as well. And then any other type
of array that you create, we can set those just fine. And we can take
another array value. We could set that to that as well as long as
they're the same type, like we've got our float
plugged into our float array, name plugged into
our name array. The same goes for all the
nodes that I've been using. So our loop arrays, if I quickly show you, we can take our
example float array, I can drag out and I
can search for loop. And you see we've
got those same nodes for I create a new loop node. We've got that array element,
but instead of a name, it's just a float value because this is an array
of float values. But our index stays the
same because it's always going to have an index for
each entry in our array. We can also make a race for our actor or objects references. So if I do that quickly, just call this the actors array. You can see that if I
change the type to actor, we go to our actor
object reference. You can see that we now
have an array of actors. And this works again, the same as we've been using
our name and float arrays. We could loop through
an array of actors. And that will give us
an actor output and an index that that actor
is app in our array. Now the engine has some nodes built-in that actually
output arrays. So an example of this would
be the overlapping actors. And this essentially gets the actors that are overlapping
our current blueprints. So I'm in the
ThirdPersonCharacter. This would get or any app to as overlapping our character, outputs them as an array. We could use this
just like we've been using our array variables. So I could, for example, loop through all of the actors that are currently
overlapping my character. And we could do any sort
of check we wanted to, we could say, maybe
destroy them. If we wanted to,
we could destroy those actors that are
overlapping our character. And we can use
this array element just like a normal variable, like we did in our previous
lesson with the actor type, we can use this to say
get their locations. Or we could use it to
set their locations. Just like a normal
act of variable. Of course, we don't have to use a loop node to do that either. We could use the get node
and this will just get us the first index in the array of actors that are
overlapping our character. If we wanted to get through, get say the second or the third, we could change
this input value. And then we could use our
get node to plug into any of these nodes that we can
use with active variables. So that's it for this lesson, and that's it for the variables
section of the course. In our next lesson, we're
gonna be taking a look at functions and how they work and how we can
create new ones.
12. Basics (Functions): Hey everyone. In this lesson we're gonna
be learning about functions, how they're used and
what they're used for. Functions are self-contained
pieces of code that we can modify and
reuse really easily. So to start with, in my
third-person character here, I'm just going to
create a new function. And we can do that by clicking the new function button here. Or we can go to the
Add button and select new function that's going to create a new function for us. I'm going to call mine example. You can see that
it's also opened up a new event graph for
us with an input. And it's got the name
of our function here. Now in here is where
we will be coding our function if you ever need to get to a function's code. So you're in the
Event Graph and you want to get your
function's code, you can always just
double-click the function name and it'll take you
straight to your function. Now as you can see, we've
got an input node and this will run whenever
our function is run. If we go to the
Event Graph and we drag out our example function, you can see that it's given
us a new node called example. Now, whenever this input
execution pin has run, the code inside our
function will be executed. So as a quick example, if I add a print string to
my example function here, in our event graph, I'm just going to create
a begin playing node. And I connect this up
to my example function. Now when the game starts, our example function will run, and that will run the
code inside our example, which is this print string. So I'm just going to
compile hit Play. You can see that our
print string is running. So to show you how
this could be useful, we'll exit out of playing, go back to ThirdPersonCharacter
and we'll create a new function and we'll
call this increase health. And we'll also create
a new variable, and we'll call this
current health. If yours is an integer, you can just click this and change it to an integer
and we'll compile. Now, you'd think if we wanted
to increase the health, we would go to our Event Graph, were dragged out from our
current health to get health. And we would use an add node, add the mountain that we
want to add to say one. And then we would then
set the current health. But the problem with this is every time you want to change
our health and our code, we'd have to write
all these notes out. What functions allow
us to do is basically take this code and put
it inside a function. And instead of having
to write this code out, we can just drag
one function into the Event Graph or another function and
have that code run. So if we take this code, we'll just cut it and go back to our
increased health function. Will paste this in
and connected up. Now currently, if we run
the increase how function, all it's gonna do is add one health to our
current health, which isn't particularly useful. We wanna be able to
choose how much health is added to our current health,
and we can't do that. So if we select our
input node here, you can see over in
the Details panel we have inputs and outputs. Now we can add new inputs by clicking this little
button over here. And that'll add a
new variable input. You can see that we've
got an input here. And if we go to the Event Graph and dragging our
increase how function, you can see that
that variable is also available here as well. Now, we can rename this by
going back to our function, selecting the input and
we'll change it to mount. We can also change the
variable type over here. So minus gone to
integer by default. But you can change it to
whatever variable you like. We'll use integer
for now because that's what our
health variable is. And we can drag out
from our amount and plug that into the
plus node here. So now what will happen is when our increase health
function is run, it will take whatever
the amount is plus that to our current health
and set the current health. Now, I'll drag out
from here and add a print string just so we
can say if this is working, we drag out from the set node and plug it into the
print string node here. Now, in our Event Graph, we want to run our
increase health, say when I press a button, so I'll right-click and
search for input event. Say why. We'll scroll through and find the
y input of them. This will just run whenever
I press Y on my keyboard. If I plug this into increase how fast I can set the amount. So I'm going to set to say five. So now when we compile
and we hit play, every time I press Y, you can see that my current
health increases because it's increasing it by five
every time I press Y. Now we can also add
outputs to our function. So if we go back
and exit the play, we can go back to our increase
health function here. If we select the input node, we can add new output. So I'm going to click
the new output button here and you see it's created
a new node for us now. And this is what we
run when we want to output something
from our function. So if I plug this into
the anterior after I print string in C that
I can give it a name. So I'll just put current health. And we'll take whatever our current Health value
is and output that. If we compile and go
back to our event graph, you can see that now our node on the event graph has an output
called current health. And this output, whatever values we plug into it
from our function. So at the moment,
I'm just outputting my current health value. So we can access that
in the event graph. Now we can also use functions
inside of a functions. So if we go to our increase health function here,
and in here, we, maybe we wanted to play a sound every time our health increased, we could create a
new function that plays a sound at our characters location that we could also use another places
if we want it to. So for example, we'll
create a new function. We'll just call this play sound. Play sound player. Location. In here, we can drag out from our
input and use the plates sound at location
node will drag out from location and do
get actor location. This will play a sound that we set at the current
player's location. Now, we can add a new input for our sounds so we can choose
which sound will play. A quicker way. We can do
this as if we drag out from our sound input here and
drag this to the input node, if I let go, you can see
it actually just adds a new sound input for us
and names that sound. If we want to rename it, we can, we just do that in
the inputs here. And now, when we compile, if we go back to what increase, how function, we can now drag that new function
we just created into our increased function. We can use this like we
can in the Event Graph. So if I connect this up, now we can say sound
because we added the sound input to our function. And whenever our
increase how function runs and run the same code increasing our health
by the amount. It will print string
the current amount, and then it will run the
code inside our play sound at location using
the sound we set. Currently, I haven't
set a sound. And then once that sounds played and this
function is finished, it will then continue and return our current Health value
in our Event Graph. And of course, the play sound at play location is just a function like our
increase health. So if we wanted to, we could
use it in the event graph as well and other places or
inside of a functions. Now one of the best things about functions is they're reusable. So I've got my increase
health function being run here on the y input. But I could also use
the increase how function in other parts of
my code if I wanted to, I can have as many as I like. And when everyone gets run, it will run the code as
you would expect it to. Whenever we modify anything inside our increased
cell function. So say we wanted to
make a change in here or if there was a bug
or something like that, we could make a
change in one place inside or increase how function. And that will affect all
of the places that we've used are increased
health function node. Functions also have
another feature called local variables. So if we open up the heart
increase how function here you can see down in the bottom
of the My Blueprint panel, we've got the local variables. Now a local variable
operates pretty much the same as a normal
variable, is just that. It only exists
inside our function. So we can't access
a local variable in the event graph from our
increased health function, we can only access them inside
our increased function. Another thing of local
variables is once this execution or once
our function is finished, variable will be reset
to its default value. So as an example, if I
create a new variable, hip and cool this example. And this is just a Boolean. So if we do a get node here, and we'll also create
a print string. Now, when we run this
print string node, I'm going to plug in my
example to the string. It'll print out
either true or false depending on what our
current example value is. By default, it's set to false. Now, after that, if
I set it to true, you'd expect the next time
we run this code it to return true because we're setting it to true
after we print string. But it will always return
false as you can see here. Because every time our
function has finished, that variable will be reset to its default value,
which is false. Local variables are
a great way to just temporarily store
information inside your function without
having to create new variables that can quickly add up if you've got a lot
of functions going on. There were also quite good
for organizing your function. So say you had a bit more code
going on and you wanted to store variables just
to keep things tidy. You could do that as well. Another useful thing
you can use to keep your functions tidy as
we have our inputs, say, for example,
our MT input here. And that wire is going
into our ad note. Now, maybe in the
future you have a function that has
lots of inputs. You'd have wires going off all over the place and it
wouldn't look very tidy. So what you can do
instead is you can right-click and
such forget amount. You can see I've got access
to the amount variable, but I don't have a local
variable called amount. There's no normal
variable called amount. This is basically
just a shortcut to this amount output here. So instead of having
the wire plugged in from our input of them, we can just drag this in here
and we can get that value. And all that's doing is
essentially just cutting out the wire and accessing
that amount variable, kind of a shortcut. Now, functions do have
some limitations. So for example, we can't use latent nodes inside a function. Now we haven't covered
Latent notes yet, but we will in a future lesson. But just as a quick rundown, if we right-click and the event graph here and we
search for today, we can create a delay node. Now, a latent node will have a little clock icon in the
top right-hand corner. And basically what a
delay node does is it gets an input and then
whatever our duration is, it wait that amount of time
before running the output. So it just allows
us to hold up code. So for example, if I was
plugging my play note here, and I'll just set
this to say three. And then I plugged my
increase health in here. It would begin play, would run, a delay node would
then get executed, and it would wait three seconds, and then it would run
the completed output. Now, because this
is a latent node, we can't use it
inside the function. So if I go to my
increase health, fair, and I drag out and I
searched for delay. You can see that that
delay node isn't coming up because it's latent and we cannot use those
inside the function. Next, we're gonna look at
pure and impure functions. So if we go back to
our event graph here, and I create a new
increase how function. And over in the Details
panel you can see we can change it to
a pure function. So if I take this on, you
can see this will also affect all of the other
increase how functions, it changes it into
this function. Now, the way these work is for every output connected
to our output pins, this function will run. So as an example, if I take my beginning Plano
tip and I'm just going to use a set
current health. And we'll connect up to here, will increase the
health by say one. And we'll connect this
up to current health. So say I hope with 0 it would increase it by one and then output a
new current health. So this would be one. And if I was to copy and
paste this set node again, and we'll connect this to here. This node would be one, but then this node would run
again for this set node, and this node would
actually set it to two, and then so on and so forth. For every connection, we'd run this node again and
increase I hope value. Whereas an impure function, if we select our function
again and click on tech P0, if we connect this backup
to begin playing out, this will always return the
same output had when it ran. So when the game starts will increase our
health from 0 to one. We'll set that value here. This value will be set to one. And then this one will
also be set to one because it will only run
once when it gets executed. And then it stores the values of its output in these pins. And then every connection
we have for that will be the same until we
run this function again. That's just something
to remember when you're working
with pure functions, is however many connections
you have connected to that function is how
many times it will run. If you have any sort
of math going on or anything like
increasing health, every time you drag
out and set something, it will run again. So your value,
your output values may be different
each time it's run. Next, we're going to take a
look at overriding functions. Now, if you haven't
seen it already, I recommend going
and taking a look. We've got a variable's lesson
on actors and objects. In that lesson, I go into inheritance and explain
a little bit about that. But essentially, any
object that exists in the world is an actor,
including our character. But then we have
different types of actors like our character here. And we can access the act of functions
or the functions that exist inside the actor through this override option here
on the functions tab. So if we click that,
you can see that we've got on the right-hand
side it says actor. Now these are functions we can access that exist on the actor. And we have them because
we're a character, but we're also an actor. If you go down a
little bit more, you can see that we've got
some that say character. Now we have access
to these functions because our third-person
character is a character. And if we go down even further, you can see that we've
got **** ones as well. And we have these because our
character is also a ****. And whenever we select one
of these functions here, we basically tell the engine, we don't want you to run
the code that exists in, say, the character blueprint. We want to take this function
over and run our own code. So for example, we
could click, can jump. And you see that
we've now taken over that function from
the character class. We can write our
own code and have now not all functions
will look like this, where we have a
separate editor if we create or if we override
another function, say the destroyed,
that will actually create what looks like an
event inside our event graph. And the reason it does
that is just because our destroyed function
doesn't have any outputs, but can jump does so
it has an output here. And whatever we
returned here will basically be checked
whenever we try to jump. So currently if I
tried to jump now, I wouldn't be able
to because we've taken over the function and we're just telling it we can't jump with set this to false. So we could have our own
code in here that controls whether or not we can
jump, for example. Now, you may be wondering if we can override
these functions. Can we actually go and find where these
functions are and look inside and see what's happening like we can with the
functions we've created. Unfortunately, these are
C plus plus classes. Actor, character
important are actually created in C plus plus and
that built into the engine. There's no blueprint
we can go to. We can first-person character, for example, and look
at these functions. You can do it in C plus
plus if you'd like to, but that's a little
bit more advanced. Lastly, I just want to
show you how you can call functions from one
blueprint inside another. So if we go to our
third person map here, I'll just create a new
blueprint class quickly. There'll be an actor,
call it trigger, will drag it into
the level here. And I'll open that blueprint up. We'll add a new component
and we'll call this box. We want the box collision and I'm just going
to move it up. And we're also in
the details search for hidden in Nin game. I'm going to untick this
just so I can see it. And then we'll get rid of that search and we'll
scroll down to the bottom. We'll do say on actually, we can go to Event Graph, which create new function. Sorry, event would
do, begin to overlap. Now we've used this node before, if you remember in
our previous lessons. But essentially this event will run whenever something overlaps our trigger and it will
give us a reference to the actor that overlapped us. So we can drag out from this. And I'm just gonna do a cost
to ThirdPersonCharacter. Now if you remember
essentially what cost does is it checks, is this input
object a character? If it is, we'll run the
top x cube in here and it will give us access to
that character is variable. Now again, in the future there
will be a casting lesson, but this is just
a quick example. If you remember, we can
access variables using this. So we did this with our cubes. We can also access functions. So if I drag out
because I'm casting to the ThirdPersonCharacter
Blueprint and that's what we've
been working in. If I drag it out and I
search for increase health, you see I can get that
increase how function. And if you remember,
we set it to, if we head back to
our characteristic, we set our increase
our function to PO. So if I untick this
and make it impure, need to disconnect this one because it will give
us wanting otherwise. You can see that it's
actually updated here. And using that we can
access the functions that exist in our third-person
character in another blueprint. This function will run as if we just run it in our
third-person character. But instead we can actually
now run that whenever our, say our character overlap. So I'll trigger, so we could increase its health by say five. Now, when we hit play
and I run over that box, you can see that
it's now printing out that increased health value. That's gonna be it
for this lesson. Hopefully you understand
a little bit more about functions now and
then our next lesson, we're going to take
a look at macros.
13. Basics (Macros): Hey everyone, In this
lesson we're gonna be looking at macros. These are similar to
functions in that they're self-contained pieces of code that we can reuse
around our blueprint. We'll also be learning about
when you might want to use a macro instead of using
a function as well. So let's get started.
We'll create a new macro. We can do that in the my
blueprints panel here. You can either click the
new macro button here or go to the drop-down
and select macro. If we click that, we can
call our new macro example. You can see that it's also
opened up a new editor for us, like it does with a function. And we've got an input
and an output snowed. Now, unlike a function, you can see that we
don't actually have any inputs and our macro, and that's because we need
to add them ourselves. So over in the Details
panel here we can click the plus symbol and we can
create some new inputs. Now, we can actually create execution pin
inputs and outputs. So if we click the Create new output option
here for the outputs, you can see now I've got an execution input and
an execution output. And if we can pull this,
go to the Event Graph, could actually drag this macro
now into our event graph. And you can see we've
got both our input and outputs and we can rename these as well,
something a bit better. So rename this to
say in this 12 out, just to make it a bit clearer. Now the cool thing with macros
is you can actually have multiple execution
inputs and outputs. So if I wanted to, I could
add another execution output. I could call this a out to. And we could run
some code and hair. And then depending on
what that code does, we could run either
one of these outputs. Just like our functions, we can also have variable
inputs and outputs. So for example, I could add a new integer input and I could change the
name to say amount, like we did with our function
in our previous lesson. You can see that now we've
got an amount input. If I head back to
the Event Graph, you can see that we've got
that in execution pen, and we've also got
a input as well, and then both of our outputs. Now the way we use
macros is very similar to the way we
use functions in that we can have multiple of the same macro anywhere
in our blueprint, we can use macros inside of
other macros if we wanted to and if we make any
changes inside the macro. So for example, if we
added some code in here, it would affect all
of the macros that we have created from
that macro type. So all of these macros
would get updated with the changes that we
make inside our macro. So now we've set up our macro of a few different
inputs and outputs. We can code in here
just like we can in the Event Graph
or in our function. So in our last video, I set up a health
increase health function. I can do the same
thing with macro, so we'll create a new variable, we'll call this current health. And we'll set it to integer
if yours isn't already. And we'll drag that
in a add node. And we'll add the amount. And we'll drag out from the output of our Add
Node and we'll do set current health like this. Now, because this is a macro, we can have multiple
output execution pens. So we could do a check, say, is our current health
equal to say 100? If it is there, maybe we want to run a different execution pen. I use a branch node here. If it is at a 100, we'll run the top output, and if not, we'll
run the bottom one. You can rename these, say max health for the top one and not max health
for the bottom one. Because maybe we want it to have different code run
depending on if we're Max Health or not. So if we then go back to
our event graph here, you can see that both of our example note
here I've updated, so they've updated the outputs. And that's because we've
changed their macro. And we could run this now and
increase our health value. So if I say put this to 50 and we'll add a
new inputs event. And what would you use, say x, which find the x input of m. So when I press X in
game will add 50 health. And then we can
run different code depending on if we're
Mac self or not. So I'll just use
the print string because they're easy
to see in game. So we'll call max health
and we'll copy and paste. This will run max like that. So we'll component. So now we can hit play
and see if this works. If I press X, you can see
currently not max out. If I press it again, we now
are turning max health. So that's just an example of
how we can use macros to run different code in our blueprints
depending on a value, for example, now the engine actually includes a lot
of built-in macros. So for example, r is valid node if we right-click
and such what is valid, and we scroll down to
the is valid node. You might recognize
this from one of our previous lessons. This is just a macro and
it's built into the engine. So if we double-click it, it actually takes
us to a blueprint called standard macros. And this comes with
the engine and you can see that this is just a macro, just like our example macro. It has the same sort
of layout and we can see the inputs as well. So if we go to standard macros, see over here the inputs. So it's just got
an execution pin. Input and an object pin and
then to execution outputs. And all this is doing is using the valid function that's
built into the engine. Checks. Is the input
object valid and then uses a branch to either run
is valid or it's not valid. There are other macros that come with the engine
that you can check out. They're all in these
categories here. So if you want to, you can look through those and
see how they work. But essentially macros are
really useful for smaller, self-contained pieces of code that you can reuse a
lot on your project. So for example, maybe
you wanted to check, is the character dead? So instead of getting
the health checking, is this less than or, is this less than or equal to 0? And then running an F node, you could actually just
take all this code, cut it, and put it into your own macros so you could have is dead. We could chuck this in here. And if we actually drag from our execution pen to the input, and we can do the same
with the outputs. So we can do like this. It just makes it a bit quicker than having to add
them all in here. So now we've got a
little macro here that we can use to check is
our character dead. So we can just drag that in. And instead of having
to add all those nodes. And every time we want to
check is the character dead, we can just drag
it in one little macro and it does
that all for us. This is really where
their strength is with macros, you
can use them a lot. They can control which
code is being run. And they're just
handy little tools, especially for things like checking values, like
we're doing here. Another benefit of
macro says you can use latent nodes in them. So if you remember from
our previous lesson, you can't use a delay
node inside a function, but you can use
them inside macros. So if I wanted to, I could add a delay
node and here, so quite a delay. You can see I can
add that in just fine. I can compile it. And if we go to our event graph, you can see now is that macro is latent because it's got the
little clock there. And that's because inside it, we've added this delay node. And the reason for
this is macros run as if they were code
in the Event Graph. But instead they just
compacted down into OneNote that we can reuse
and edit really easily. They also don't reset functions do every time we run them. So they're much more similar
to code that we have in the Event Graph rather than code that you
have in a function. Now, some things you
can't do with macros is you can't call them
from other blueprints. So if you remember in
our previous lesson, I create a trigger and
we can do that again. If we create a new
blueprint class, we'll sell it to an
accent and I'll call it trigger, will open that up. And I'll create a new
box collision component. And we just move this up a
little bit and we'll set it to hidden in game will take this off so
we can just see it. And in here we'll create
a begin overlap node. If you remember, this just runs whenever something overlaps our trigger and then it'll give us the actor that overlapped it. So drag out from here and use the Cast to
ThirdPersonCharacter. And this will take our actor output that
overlapped or trigger. And it will check, is it a
ThirdPersonCharacter for is, then it gives us
access to that fire a variable and we'll run the successful pin
here at the top. So if you remember, we can call functions via this. But go back to my character here and I'll just
create a function. We'll call this say
increase health. And we'll just compile. I won't add any code and
we go back to our trigger. If I drag out, I can or I can access that function so I
can go increase health. You can see I can call that
function from my character. But if you remember, we've got r is dead macro. If I drag out and I
search for is dead, I can't find that
macro because it's not accessible from my
Character Blueprint. I can only use it within
my Character Blueprint. Lastly, if you remember
from our previous lesson, we can override functions
from our parent blueprints. For example, because this is a third-person
character blueprint, that's a child of the character. I can override functions that exist in the
Character Blueprint. But you can't do
this with macros. Macros exist only in
our blueprint hair. I can't override and take control of any of
the macros from say, the character blueprint or the active blueprint
for example. So just to summarize, macros are really useful
tools that you can build that can just make your
life a little bit easier. So you don't have to
recode stuff all the time. And you can modify them
just in one place and it will affect all of the
places that macro is used. They can also control which code is being run really
easily because we can have multiple
execution inputs and outputs.
14. Basics (Structs & Enums): Hey everyone. In this lesson
we're gonna be taking a look at structures and enums. So let's get started. Structures, or sometimes
referred to as structs, are a way of storing
multiple different types of variables all
inside one variable. So to give you an example, I'm just going to
create a new variable. I'm going to call
it example straw. And we're going to set
the variable type to a structure that actually comes
built-in with the engine. If you want to find the other engine structs
that come with it, you can just go down to
the structure category. And here you can see all of the structs you used
throughout the engine. Chances are you won't be
going in here very often. Because these are
just used mostly for engine functions and
things like that. But we're going to use
one as an example. So I'm going to create, or I'm going to set our
variable type two named float. And we'll set our
variable two names float, and then we'll compile. Now that we've compiled,
you can see that our default value includes a float variable and a name variable that we can both individually
if we wanted to. And they operate the same way you'd expect a name or a
float variable to work. Now, this struct only includes two variables, a
float and a name, but you can get struck with many more variables and different
variable types as well. Now, we can get and set stroke sustained way we can with
any other variable types. So if we drag in our example struct here you can
see we can get it all. We can create a set
node and it gives us these nodes that we've seen before with
other variable types. Now, the cool thing about
structures we can access these variables are
stored in it very easily. We can just drag out from our get node and we can
create a break node. Now because I'm
using named float, it says break named float. But if we were using a different structure
with a different name, it would say break and then that structure's
name instead. So it will create the Blake
break named float node. And you can see here
that we can now access or float variable as well
as our name variable. And these are just
ordinary variable pins. Now if we wanted to,
we could drag out from our float and we could
create an add node, for example, or any other
float Related node. And we could do the
same thing of our name, variable output as well. If we had say, a float variable, we could set that float variable
using this pen as well. We can also get the pins hair in a different way
if we get enough, again, note it, and we
right-click on the output pin, we can select the Split
Struct Pin option here. You can see that now
we can directly get the float value and our name value from the
example struct variable. And if we want to
recombine them, so it goes back to our normal
default get node here, we can right-click
the output pins and select recombine Struct Pin. You can see that it now
goes back to normal. I will say however, with my experience
in the engine using this Split Struct Pin option, instead of using the break node, this is a little bit
more prone to breaking with engine upgrades
and things like that. So personally I prefer
to use the break nodes, but It's a personal preference. You can use the split
pins if you want to. So now we know how to get information from our
strokes get node. We want to be able to set information to our
strokes, which we can do. So if we take our
set note here and drag out from the input pin, will search for make. You can see that we've got an
option for make named flow. Now again, if we were using
a different type of struct, it would say Make and
then that strokes name. So we'll create this note here. You can see that we've now got a float input and a name input. And this allows us to
set off flow or are named variables
in our structure. Now the one problem with this
is say we only want it to change our float value and we didn't want to change
our name value, we just wanted to
leave that the same. This would actually
overwrite our name value. So what we can do instead, if we want to just change one of the variables inside our struct, we can do is we
can create a node, drag out, and search
for set members. And you see we've got set
members in the non struct name. So again, ours is
called named float. So we'll say set members in named flow will
create that node. And we get this
odd-looking note here. In the Details panel. We can go down to
this drop-down. Can you see that we've got
a tick box for each type of variable that is
inside our struct. So if I wanted to just
change the float variable, we can take that on here. And you see that that's now
added an input for our float. Now, when this node runs, we could set a new
float variable inside our struct without
affecting our name variable. Whereas with the set node, we would have to set both our float variable
and our name variable. And of course, if you had a
struct with more variables, those would be listed in here. You can take on
multiple variables using the set members notes. So if I wanted to, I could have both of these pins here
as an input as well. And we could change
both of those values at the same time. This node automatically
acts like a set node does. So we don't need to use a set node for these
changes to apply. Just when this node gets run, it will change those values
for us inside our struct. So, so far we've been using this named float struck that
comes built into the engine. But we can actually create
our own strokes and we can choose what variables are
gonna be stored inside it. So to do that, we'll go to
the content browser here. I'm just going to right-click
and an empty space. Then we want to go
to the blueprints pop out and we'll
select structure. Now what if you name
your structure is what the structure will be called and the variable types option. So I'm just going to call
mine video struct like that. And we'll double-click
it to open it. I'm just going to put
mine up in the top here. You can see that we've now got an option where we can
set our variables. So by default we've just got a Boolean variable that's
called member underscore 0. We can add new variables up here by clicking the
add variable button. And if we want to, we
can remove variables by clicking the little trash
can here to remove them. So we'll add a few variables. And you can imagine if we wanted to store information
about say, an item, we could use a struct
to do that and keep all of that information
stored in one variable, instead of having to have hundreds of variables
describing an item. So for example, maybe we wanted
our item to have a name. So we would set the item name. We could call this
name maybe a weight. So we will use float. We call this variable weight
maybe a damaged value. So we could say an
integer to damage, and then maybe a
texts that we can say is the description. And we can save this. Now when we go back to
our ThirdPersonCharacter, we can create a new struct. And we'll call this our video. And when we go over
to the variable type, we can search for a video. And you'll see video struct. That's the name
of our structure. If you called jaws
something different than you will have
to search for that. So we'll create this
and we'll compile. So now when we go over
to the default value, you can see that we've got all four of our variables
that we created inside our struct with the right names and see
if we can set name, a float, an integer, and a description
for our struct. And just like before, we can access these with
the brake note. So if we create a node, we drag out and we create
a break video structure, you can see that the engine just automatically sets up for us so we can just
create that node. And just like that, we've got
access to our name, weight, damage, and description
using our break node. Again, if we wanted to set those variables using
the set members node, we can drag out, use
the set members. And you see set members
in video struct. And we can take on any
variables we want, like we did before
with our named float. But this is now our
own custom struct. Now, we can also set the default values for our
structure as well. So if we go back to
our video strokes, you can see we've got a
default values option here. So here we could just sat what the standard default values are for the video Struck type. So maybe I just want
to say, say item name. We wanted the default
weight to be say one and description which part? Item info here. And the damage will be ten. So these are now the
default values if we save now and we go back to
ThirdPersonCharacter. And I select my video
struct or compile because we've made some changes to the structure, will
have to compile. You can see that now it's using those default values that
we set inside our struct. If we want to get back to being
able to change variables, we can just click
the Structure tab here and we can access
those variables. Now, one other thing you can do in here
is if we wanted to, we could reorder
these so I could grab this little icon
at the end here. We can change the
order, so maybe I want the name to be third
now instead of the top, we do that and we can hit Save. Go back to our character
and we'll compile. See that now with our
video stroke selected, that they're now in
a different order. Now it's something that
makes structs really powerful is that we can
use them in arrays. So if you remember from our array video to set a
variable to be an array, we can click this little
drop-down here and select array. Now let's kinda break a few
of our connections there because we can't plug an array into either
one of these nodes. So I'm just going to
delete those for now. But if you remember,
we can drag out from an array variable
and search for loop. We can select for each loop. Using this, we can now loop through our entries
in our array. So I'm just going
to compile here, so we've got our default values. So for example, we
could use a struct to store lots of information
about different items, maybe for an inventory,
for example. So for example, if I
create a few inputs here, you can see that now we
have multiple versions of that struct
stored in the array. And then we can loop through
those versions of our struct using the loop node and then access their information
using the array element. And then we can just use the break video strapped
like they have been before. And we can access that
information from our array. So that's pretty much
the basics of structs. They're really useful
for keeping things organized and storing
big amounts of data. Like if you had an
inventory full of items. You can use these to store lots of information
about each item. And then we can put them inside a ray or we can use strokes just to keep
things organized as well. Maybe you've got a set of variables that you've
always used together. So you could store
those in a struct and just access them
through one variable. Next, we're going
to look at unions. Now. Again, like the struct, the engine actually
has built-in indium. So if you go down to
the bottom, you can see the idiom category here. And there's lots of ones
that come with the engine. Again, you won't
really use these. They're just sort of
built into the engine and use by nodes
within the engine. But you can also create your own enums just like
we did with our struct. Now, I'll show you
how to do that. So it will compile this
blueprint for now. And we'll right-click
and our content browser will go to blueprints again. And here we're going
to select enumeration. And we'll call this a video. Again, whatever you
call this blueprint is what it will be called in
the variable type option. So that's just
something to keep in mind. We can open this up. You can see that it
looks a little bit similar to our
structure at the top, but there's some
differences here, so we don't actually
have any default values to start with. We'll click Add in numerator. You see that this gives
us a new input here. Now all we can set a name, so we could say option one. And we'll add a couple
more just so we can see it in the editor. So we'll call this option two, and we'll save this. Now, there's not really much
more you can do in here. So we'll go back to our
ThirdPersonCharacter. And I'm going to
create a new variable. We'll call this a video. In it. I'm going to change the
variable type here. I'm just going to
change it to a single. And we'll click the
drop-down and we're going to search for our video in you. Just like that. And we'll compile. Now you can see in
the default value here we have this drop-down. You see that? Because I've got option
one and option two that I sat up in my video union, that they're the options I
have for my default value. Now, enums work the same as most variables we can
get and set them. So if I drag out and
I do a get node, you can see we can just get
it like a normal variable. And we can also set it. So if I drag out and do set, you can see I've got a set node, but we can actually
just manually set whichever option we want pair
using the set node as well, or we can take an
input if we wanted to. Now, enums are actually
really useful at controlling which code is
being run in your project. And the way they can do that is if we drag out
from our get node, we can do a switch. You'd see switch on video. Again. If you're in humans called
something different, it would say switch on
and then that enums name. But ours is video indium. So
we're going to create this. You can see that it's created a switch node for us and for every setting we have
inside our indium, it will give us an output pin. So if we went back to
our video in num here, I added a couple more options, so we'll add a couple more. I'll just set this
to say test 123 and test 456. We save this. Now when we go back to
our ThirdPersonCharacter, you'll probably want to
compile just to make sure you get those options
Update being seen. Now, we've got our
two original options and it's actually added
some additional ones. And using this, we can
actually control which code is going to be run depending
on what our enums set to. A good example of how this
can be used as maybe you have items in your game and different items do different
things when they use. So maybe you had consumables, medicines, things like that. You could have an
option for each one of those different
item types and then have different code be run depending on which
item type it is. Now, we can also use a
select note of them. So if we drag out, we
search for select. We can actually select a variable depending
on our enums value. Right now it's just
grayed out because we haven't input
any variable type. But if I was to create a new variable and
we'll call this float, I'm just going to
set it to a float. If we plug this float now
into the select note, you can see that they
all become floats. And this can allow
us to select and output from this return value. We can select any
one of these inputs depending on our Indian value. So for example, if we were
to set it to option two, then whatever is
connected to option two would be returned through
the return value. Now, we can also do things like controlling a branch
node using enums. So if I just delete
these nodes for now, we can drag out and
do an equals node. We can check. We can create this equals
Ethereum node here. And we can check, is our immune equal to one if
it's sharp options? And if it is, we can output a true value, and if not, it will
put a false value. So we could create a Branch
node him and control whether or not this is
going to run true or false depending on
our unions value. Now we can also use our
indium inside our struct, so we can do that
now if we wanted to, we could go back to
our video struct here, add a new variable, and we'll call this
say item type. We can set this to
be our video immune. Just like that. Save this and maybe we wanted to change what
our options were. So maybe this was food, drink, met, and weapon. So now we could use this video indium inside our struct to set what
an item's type ID. So if we go back here and
we get our video struct, we can say loop
through our array. We can access all of the values in our structs
so I could drag out, break our video struct. You can see that
now we've gone past a certain number of variables. So we get this little drop-down
option that we can use. And you can actually
organize this further. So maybe you only need
the weight value. So you could go in
here and untick certain variables that only
the Weight option shows. Now, just to keep things
tidy because you might have a struct with
lots of variables. So you can untick which ones you just don't need at
that particular moment. This doesn't affect
your struck in any way. It just tidies up the node. But we can also access
that item type in him that we added to our struct. So if we drag out, we can
use say, the equals node. We can check is this item, this particular
entry in our array? Is it a food item, for example, if it is, then maybe we want to run
a specific piece of code. Or if it was say, a weapon for example, we could have it
run different code. As I said before, we could
use that switch node. So we could run a
switch on video. And now we can switch
depending on what type of item this entry in our
array happens to be. Now That's it for this lesson. Just as a summary, structs
are a really good way of storing multiple variable
types inside one variable. And then with arrays
we can store lots of information that we can
then really easily access. And enums are a great way of controlling which code in your
projects that's being run. Or we can use them to select variables depending
on the nums, fantasy.
15. Basics (Events): Hey everyone. In this lesson we're
gonna be taking a look at event nodes. Now we've already been using event nodes quite a bit
in our previous lessons. If you remember the beginning
play note for example, that is an event or events destroyed node
is also an event. These events are called from
code inside the engine. Code that's built
into the engine runs these events when the game starts or when the
actors destroyed. Now, we can also create our own custom events that we can run whenever we want to. Do that, we can right-click. We can search for custom event. And we can use the add
custom event option here to create a new event node. I'm just going to
call mine example event, event like that. And you can see that now it
looks like our other events, but this event is actually
never going to be called right now because we
haven't called it anywhere. So if I wanted my
example vent to run and see the code
I connect to it, like print string to run, we would need to call
our example event. So to do that we can
use an existing event like the beginning
plane note to call it. So we could drag out and
search, for example, event. And that would now call our example event
when the game starts. Now we can call events in
multiple places in our code. So for example, if we wanted
this example event code to run when the game starts and also when our
characters destroyed. We could do that as
well. We could just drag out at another example event. Cool here. And now
when our game starts, we'll call this event,
I'm running its code. And also when this
actor is destroyed, we call the event
and run this code. We can also add
inputs to our events. So if we select our
event note here, you can see there's
an inputs option. So if I click the add
input button here, we can see you've got
a new Boolean input. And that adds an output to our event node and also inputs
to our event cool nodes. So now we can control a
variable using the core nodes. So for example, maybe we
wanted our boolean to be true When the
beginning play runs, but false when the
destroyed runs. And then we could have
maybe different code run, depending on whether or not that output value
was true or false. Events are also used pretty extensively in coding
for multiplayer. If we select the event here, you can see that it's got
some replicate settings. These are for multiplayer. Now I'm not going to
be covering this in this lesson because
multiplier is a huge topic and really you
need to know the basics of blueprints before you get
into coding for multipolar, it moving on, another thing you can do with events
is called them from other blueprints like
we can with our functions. So if I can pull
my blueprint here, I'm going to create
a new blueprint. I'm just going to use an actor and we're going to
sell it to trigger. And I'll open that up. I'm just going to add a box. Collision will go to
the Event Graph and we're going to create
a begin overlap. Event actor begin overlap. Again. This is just an event. You can see that it
says event on the node. But this is called when something overlaps
are trigger actor, that gives us an
output of whatever actor overlap Todd trigger
will drag out from this. We will use a Cast to
ThirdPersonCharacter node. And if you remember from
our previous lessons, this checks is the
other actor that's overlapping our trigger,
a third-person character. If it is, then it
gives us access to its variables,
functions, and events. So if I drag out from here
and I searched for example, you can see that I can
call my example event. And we also have access to
that variable we added. And when an actor
overlaps are trigger, would check, is it a
ThirdPersonCharacter? And if it is, then we'll call this example event on that ThirdPersonCharacter
Blueprint. And if we double-click
this event, it will actually take us to
our character blueprint. And that just takes us
straight to our code so we can easily find
what we're running. We can also use
events with timers. So if we disconnect, I begin play note
here and I'll just move it up here for
a bit more space. If we drag out from my Begin
Play and we search for set a timer by event. You can see that
we've got an option called set timer by them. And that gives us this node. Now, if you can poll,
you'll get an error. Don't worry about
that because we don't have an event
connected up yet. So there's a couple of
ways we can do this. We can drag out from
our event pin here, then search for custom. And we can add a custom
event like we did before. And that gives us
a new event node. Or we can just right-click
and search for custom and add a custom
event like we did before. And we can connect it up
to the event input here. Now, one thing to
keep in mind is if your event has any inputs, you won't be able to
connect it up to this node. So for example, if I added a Boolean here
and we can pull, you can see if I drag out
from my customer vent here, I can't connect it
up to the input. And that's because we've got an input variable for our
move this and compile again, I'll be able to
connect that backup. So now the timer
event allows us to run an event depending
on its settings. So currently on Begin Play, we want our timer to run, say, every 1 second, so we can set the time to one and we can turn on looping if we want this event to run every single second. So
we could take that on. If we were to leave this off, the beginning play wouldn't run. It would run the set
time I buy them. This would wait 1 second, and it would run our event once, and then that would be it. But if we have looping ticks on, it will run it every second. Now, timers are a
really good alternative to using the tick event. So if you remember, if we
create the tick event, this will run every single frame that our game is rendered. And a lot of beginners tend
to attach a lot of code to this just because it
runs continuously. The problem with that is, most code does not
need to be run every single frame and you can very easily ruin the performance of your project by doing that. So a great alternative
is using timers. Say if you needed code
to run every 1 second, you can connect it up like this, instead of using a
technique, for example. Now we can use a timer
handler to control our timer. So if we drag out from
this return value here, we can create new variable using the promotes
Variable option, and that will just
create some new variable is type is timer handle, and I'm just going
to call it timer. Now this time a variable allows
us to control our timer. So say for example, we wanted to run
this customer then a number of times and then
stop the timer running. We can do that. So we could add,
say a new variable. I'll just call this number. I'll set it to an integer. We'll get our integer
and it will just check, is it equal to
say, five to five? And we will do an F node. So if it's not equal to five, we want to add one to it. We'll do that, we'll get it. We'll add one and then we'll sex the number value is at five. We want to stop our timer. So what we can do is
we can drag out from R or we can get our
time a variable here, drag out from it
and search for clip and use the clear and
invalidate time I buy handle. So now, the way this
code would work is when the game starts or when the character
has spawned in. Our timer will run our
customer then every 1 second, we'll set its timer reference to the timer handle variable. So now when our
custom event runs, we check is number
equal to five. If it's not, we add
one to it and set it. And then the next
time this runs, after a second, we check again. And then once it is at five, we then tell this timer to stop. Now, using the clear and
invalidates the timer by handled node will
completely stop this time. You will have to run
it again to start up. But if you want to be able
to resume this timer, we can actually use
a different node. So we can drag out and we
can search for say, pause. And we can pause
the timer handle. So we can run this instead. Now, this allows us say maybe we wanted to resume the
timeout again later on. We could then use
the un-pause node that would resume
our timer running. Now we can test
this out and game. So I'm just going to
delete the un-pause noted. And I'll add in a couple
of prints strings just so we can see what's running. We'll plug in our number
two, I print a string here, and I'll add a print string
up to my pause time of code. And I will set this to time-out. So now when we hit play, this all should run
when we start the game. So we can check to see our
time is running every second. It's increasing
our number value. Once it's five, the port, the timeout is paused. Now if you ever want to find the events that come
built into the engine, you can do that if we go to our ThirdPersonCharacter
Blueprint here, click on Search for event. You can see a list of all of the different events that come
built into our character. Now, because this
is a character, it has some custom events
that other actors don't have. Like for example, the landed, this will run whenever our
character land from a jump. You can also do this in normal actors like for
example, our trigger. If I right-click on
search for event, you can see that it doesn't have as many events as
the character did, but it does have some
built and events that you can use to run your code. That's it for our events lesson. We will be using events in
our future lessons as well, just purely because they're pretty core part of
coding and blueprints.
16. Basics (Blueprint Inheritance): Hey everyone. In this lesson we're
gonna be talking a little bit about Blueprint inheritance. Now, we've talked about
this a little bit before in the actors and objects
vary up the video. If you haven't
watched that one, I'd recommend checking that out. But essentially,
blueprint inheritance allows us to create a blueprint from an existing
blueprint that it then uses that existing
blueprint as a parent. And what that means
is our new blueprint, which has the child inherits
all of the functions, variables, and code from
the parent blueprint. So first I'll set
up an example here. If we just create any Blueprint, I'm just going to right-click
and select Blueprint Class. You can see that
when we actually select one of these
options here, we're actually picking
a parent class. Now, we've been using the actor
for the most part because that's just the
most basic object that can exist in the world. So we're just going to
select actor again now. And by doing that, we inherit
our new blueprint here, inherits all of the functions, variables, and abilities
that an actor has. Now, if we open up
our new blueprint, I can show you what I mean. If we just have this
into the top PEP, if we go to our variables
option down here, it looks like we only have
our default seen route, which comes with our actor. Director actually comes with
a bunch of other variables. We just can't see them
because they're inherited. The way we can
turn that on this, if we go to this
little cog here, we can click on Show
inherited variables. And you see that
now I've got a ton of categories that
have just appeared. Now. These are all variables
that my new blueprint or inheriting because it's
a child of the actor. All of these variables
were created in the actor. Now we can use these
variables just like we can with variables
we create ourselves. So if I go to the
Event Graph here, I can drag these
in, I can get them. I can't set certain ones. So for example, only relevant to owner is actually disabled. I can't set that using code, but other ones I
can, for example, if we scroll down, I can have
can be damaged if I drag it and you can see I can get that variable just like
our normal variables. And I can also set up. And this is the
same for functions. We spoke a little bit about
this in the functions lesson, but when we right-click
and we search for say, set to transform, this set actor transform node is just a function
that exists in the actor class that
we have access to because our new blueprint is
a child of the actor class. Now, we can't go to the
Content Browser and find the act of blueprint
because it's not in here. It's actually built into
the engine and all of its variables and functions
are all coded in C plus plus. So now I'm going to
show you how we can set up our own
inheritance system, like we inherit from the actor. We could have our new blueprint, have some code in it, some
functions, variables. Then we could have another
new blueprint inherit from our new blueprint
and have access to those variables
and functions. So we'll go to the
content browser here, and I'm just going to
rename my blueprint. I'm just going to
call it the master, will call it BP
Underscore Master. Now, to create a
child blueprint, there's a few ways
you can do this. We can just right-click on
our bp master blueprint. You can see that
there's an option here called Create
Child Blueprint class. If we click that,
you can see it's created us any new blueprint. It's giving it the name BP
master underscore child, and this is now a child
blueprint of our master. If we open it up,
you'll see that instead of the parent class
being the actor like it is in the master blueprint or master child is parent
class is BP master. Now I'm just going to go
to the Content Browser and rename this to child just to, so we don't get confused
here like that. Now, another way you can
create child blueprints is in the Create blueprint option. So if we go to Blueprint class, you can see down here
it's got all classes. And if we search for
BP Underscore Master, you'll see we actually find it. It's kinda hard to see because
it's highlighted there. But that says BP master. If we click on this,
we can click Select. And that will also create
us a child of the mask. So you can see it's
created a new blueprint. If I open that up,
you'll see that the parent class
is also BP master. Now I'm going to go back to my content browser and just delete this new blueprint
because we've already got a child that
we can work with. So now if we go back to our bp master and I'm just going to delete these nodes for now. I'm going to hide show
inherited variables. So now we're back to
our default view. I'm going to create any variable and I'm just going
to call this say, example variable will create
a new function as well. I'll call this example function. Now, this variable and function are unique
to our bp master. So other children of the
access, say for example, our character, which is actually a child of the actor as well. It won't have access
to these variables because our character isn't
a child of our bp master, but our child I'm sorry. Bp Child Blueprint is a
child of the BP master. So if we go to the
or if we go back to our master here and compile
most save that as well. Then we go back to our bp child. We go into Event Graph. We can turn on that, show
inherited variables. Okay, So the drop-down,
you see that we've got all of the active variables because even though the
BP master is our parent, the parent of the BP
master is the actor. So our child still has all of
the things that actors do, still has all of its variables
are other functions. But then we add in whatever
our parents got as well. So you can see our
example variables that we can use that as
if we had created it. We can set it just
fine in our child BP. We can also use that function that we
created in the master. So if I just right-click and I searched for example function, you can see I can
create the example function and any code
that we had inside our function here would run the same as if
we had called it in our Event Graph master blueprint for we can access that
in our blueprint. And if you remember from
our functions video, we can override functions
from our parent blueprints. So if we go to override in
the functions tab here, you can see that we've got
all of these functions we can override from our actor. But we've also got
the BP master. And you can see we've got
our example function here. If I click on this, we
can takeover and change what code is going to be run whenever our example
function runs, we also have this
extra note here, and this basically makes the code that's in the
parent blueprint run. And then we could have
additional code if we wanted to. We could also just delete
this node and completely run our own custom code for whenever example
function as RAM. Now, code that's being run in the master blueprint is also going to be run for
our Child Blueprint. So it's giving you an example. I'll go to the
Event Graph it and I'm just going to
delete these nodes. I'll delete these ones as well. They just come with new
actors that are created. So you can see our child
now has no code in it. We can delete that, override some just
going to select example function
here, delete that. That doesn't actually
delete the function. If you see, I can still access the function that just
deletes are Override of it. So any custom code that we might have added
to the override is now gone and we'll just use whatever our master blueprint, um, has in that function. So if I delete that, you can see we have no
code at all in our child. Bp will compile and save this. Now if I go to my BP master and I'm going to create
a beginning play note. And I'll add a print
string to this. So just something simple
which leaves us hello. So now the only code
that we have in both of these blueprints is this begin play and
then a print string. Now, if I go to the
third person map and I drag in my BP child, and I'll just place
that in there. Now remember, our child doesn't have any code in it at all. But when I hit Play, you'll
see that it's printing hello, even though it has
no code there. Now that's because
the child will still run the code that
exists in the parent. So our parents says to
begin play print string. So I'll child will do the same. Now, like our functions, we can override events as well. So in my child now, if I create a new
begin play of m, I won't connect to
anything up to this. I would just leave it like that. I'll compile. And now when I hit play and see that No Print
String happens. And that's because we've, we're telling the
engine our child overrides its parents
begin play node. So no longer will this run
for our child anymore. We'll run our own
custom code so we can add another print string
and we could say this, this, this is a test. And now this will be run
instead of this being run. So if we hit Play, you
see this is a test. And again, if I remove that, begin playing out from my child, you'll see that it'll start
printing the hello again. Now, you might be wondering what the point of Blueprint
inheritance is. Why wouldn't you
just have all of this code and each one
of the blueprints. Well, the main reason
is because it's more difficult to
maintain if you had all of this code and say 20 different blueprints and there was a bug with that code. You'd have to go through
and change 20 blueprints. Or if you wanted to add
a new feature, again, you'd have to go through all of these 20 blueprints
and change the code. Now with blueprint inheritance, you can have one
master blueprint that has all of the
code you need in it. And then children blueprints
that then inherit that code. And if maybe one of
the child blueprints needed to do something special, but most of the code would
still need to be the same. You could go to that
child blueprint. You could override say, a function or an event and
have custom code run only in that child without
affecting all of the other children or affecting
the master blueprint. A good example of this would
be things like weapons. If you had 20 different
weapons in your game, you wouldn't want to have all of the code for shooting, aiming, reloading in every single
weapon blueprint because if you wanted to change
any of that code or fix a bug or add a feature, you'd have to go through 20 or 30 blueprints doing the same thing
over and over again. Whereas if you just had
one master blueprint that had all of your aiming
shoeing, reloading code. All of the weapons are children
of that master blueprint. You can change it all in just one place and that will affect all of the
child blueprints. Now, inheritance also covers the master blueprints
components. So if we add a new component to our master blueprint here, I'm just going to use a
static mesh component. You'll see that we've got
a static mesh component. Now we can set a mesh. I'm going to set mine
to a cube for example. And I'll just set a
cube and compile. So now we have a cube in
our master blueprint. We go to the Child Blueprint. You can see that we also
have a cube in the viewport. Now, you can also find the state mesh in
the Components panel. If we select that, we can actually change
our cube smashed. So I can change this
to say, a comb. So if I search for cone, I can set this to a cone. Now, our child has a
different stack mesh from our master blueprint. We could do the same with multiple child blueprints
of our most blueprint. Say if you had Meli weapons, for example, and you add one master melee weapon
with all of the code. And you could then have child
blueprints of it for say, a knife and acts a
spear and so on. And you could change the
stack mesh for each one of those and have them all still have the code from
the master blueprint. That's gonna be it
for this lesson. Hopefully you have a better
understanding of inheritance in the engine and also
what it's actually useful.
17. Basics (Casting): Hey everyone, In this
lesson we're gonna be taking a look at the cost node. So before we get started, I strongly recommend if you
haven't already watching the actors and objects
variable lesson. And also our previous lesson on blueprint inheritance
as casting kind of connects with both
of those systems. So to get started, we're
just going to create a new blueprint like
we've done before. Just Blueprint Class,
we'll sell it to an actor. And I'm just going to
call this trigger, which is going to
set up a basic box that our character can overlap. And we'll use those
overlap events to run some casting notes. So we'll open up our trigger. And I'm just going to
add a new component, and this will be a box
collision component. I'm just going to
move this up so that when it's in the world
are correctable, be able to overlap it. And I'm also with
our box selected. I'm going to search for hidden. And I'm going to untick
hidden end game here, just so we'll be able to see our box while we're
playing in the game. Then in the event graph, I'm just going to
delete these nodes are right-click and search
for begin overlap. I'm going to use the
event begin to overlap. And if you don't remember
from our previous lessons, this node will run whenever
any actor overlaps our actor. So overlaps are trigger. This will run and it
will give us a reference to whichever actor over lactose. So the output of our begin overlap node
is an act of reference. And if you remember from that, we can use this to access any of our actor functions or
variables or events. But maybe we wanted to
access information that was in our character when it
overlaps are trigger. Now to do this, we can use cost. So if I drag out from my
other actor here and I search for cost to third person. You can see that we can cause to the BP ThirdPersonCharacter. So I'll click that and that
creates us a new car snowed. And essentially what
a car snow does is it takes in an object
and it checks, is it the object that
we're trying to costume? So taking our actor reference, which could be anything
that exists in the world, this cost node will check, is it a third-person character? If it is, then our top output
execution pin will run. And we can run code or the
cost failed would run, and we can also run
different code. It also gives us access to a third-person character
variable type. Now, this will only be
valid if the Cast succeeds. And what I mean by valid is
we can only get information through this variable
if the Cast succeeds. So if for example, maybe you had a vehicle when the level that run over our trigger, if it wasn't a
third-person character than the cost failed would run. And if we try to get any information from our
variable output here, using code that's being
run from cost failed, we'd actually get errors
because the cost had failed. So we can't actually
retrieve any information from this
ThirdPersonCharacter output. So an example of
how we can access information from our
third-person character using this variable output is we can go to our
ThirdPersonCharacter. And I'm just going to
create a new story that was an accident,
a new variable. And we'll call this
current health. And we'll set it to an integer. I'm just going to
delete this new macro. And we will save this now and go back to
our trigger blueprint. And if we drag out, we can now search for get current health. You can see that
we can now access our current health
variable through the output pin on our cost node. And if we add in
say, a print string such that in a
print string here. And notice I'm connecting
it to the top PIM because we only want this
print string to run. If our cost succeeds, we'll drag out from
current health and just connect that up to
our print string here. And I'll get back to my
ThirdPersonCharacter, select my current health. I'm just going to set the
current health to say 50. So now when we play and
I run over my trigger, it will print string the value of our health. So hit Play. We're going over my
trigger and you can see that it's printing out value 50. Now if you remember from
our previous lessons on events and functions, we can also call those
using our cost node. So if we exit the plane editor, go back to our character. I'm just going to create
a new function or cool this example function. And we'll add something
like which saddle them, print string and hair
because it's easy to see and game example function. So this is a function inside our ThirdPersonCharacter
Blueprint, and we can call it
from our trigger. So I'm just going to compile, go back to my trigger here, will delete this code for now. We'll drag out from the
ThirdPersonCharacter pin here and search, for example, function. You see that we can now access our function that even though it's in the
ThirdPersonCharacter. And when we hit play, we
went over our trigger. You will see that
the code inside is actually being run as if that function was run inside
the ThirdPersonCharacter. The same thing can be
done with events as well. So if we go back to our
ThirdPersonCharacter, then go to the Event Graph
and create a new customer. Then I'll just zoom in here
and call this example. And we'll just add another
print string here. And we'll put the string
two example event. Now when we go back
to our trigger. We can delete the example
function and we'll drag out and we can
search, for example. You see that I can now
access that example of them. And then when we hit play,
run over our trigger, you'll see that
it's now printing the example event print string. Now I also want to
give you an example of when a cast fails. So to do that, we'll
exit the game. And I'm just going to create
a new blueprint class, which send it to actor. And I'm just going to call
it EP underscore example. And we will open that up and
just compile and save it. I'm going to drag it. So it's in the top tab here with the rest
of our blueprints. And I'm going to
create a new variable. And I'm just going
to call this Test. And we'll compile. Next. We'll go to
our trigger here, and we're going to
remove these notes. The cost of the third-person
character we drag out from our other actor
output and will cost to our bp example blueprint. And we'll drag out from
the BP example variable. And we do get test. I'm just going to
run a print string. And we'll print string whether
or not that value is true. So now when we compile
and we run over our box, you'll see that
nothing's happening. And the reason for that
is our character is what's overlapping our box
and it isn't a BP example. So our cost is failing. If we have to exit now,
go back to our trigger and added new print string
to the cost failed. You'll see that the
Print String prints out. So if we run over it now, you can see that
it's printing hello, and that's because the
cartilage is failing. The input object to our cost
node is not a BP example. So the cost has failed. Now, if I was to try and
get information from our bp variable pin hair
when the cast fails. So we're actually get an error and I'll show you
what that looks like if we try and access
our test variable here, when the cost fails, we hook compile and
we'll run over the box. And gay, you can see that the print string node is
still running and it's running false because that's just the default
value for variables. But if we exit now you can see that I'm now
getting an error. And essentially this
is just telling us that our cost failed. We're still trying to access information from it
even though it failed. So we know that we're accessing our bp
example variable here, but the cost is failed. So that's just
something to keep in mind when working
with costs notes. I'm just going to
change this back to our ThirdPersonCharacter so
we can do a few more things. So the cost to third person, and we'll connect it up like
that and we'll compile. Now, we may want to store a
reference to the act that overlaps I trigger to use
it later on with code. So there's a few ways
we could do this. We could drag out
from our other actor here and do promote a variable. And that will create
us a new variable. And I'll just leave it called
other actor and it's set to an act to type because that's the type of
pin that this is. We could set this here. And then later on maybe we had some other code
that we were running. Later on, we could then access our ThirdPersonCharacter by just getting our other
actor variable, dragging out costing
to the third person, again, to cost the
third person character. And again, we could access those variables and functions
and things we need it. But we could also just store the reference to our third
person instead of the actor. And the reason for
this is we don't really want to cast to our blueprint every single time that we need
information from it. It's fine once or twice, but they can start adding up
and affecting performance. So what we could
do instead is we could get rid of our other
actor variable here. Because I only want
my code to run it if it's a third-person
character anyway. So there's no real reason to
store the actual reference. We can just store the
character reference. So to do that, we can delete
our previous variable. I'll just drag out from
my ThirdPersonCharacter, do promotes variable. And we'll leave it called ThirdPersonCharacter
and see that it's also set it to the BP third-person
character variable type. So we'll just save
that and compile. So now we can access all of the variables and functions
using this variable. Now, we don't have to cost another time to access
that information. So I could drag out
and I could get my current health for example, or I could access those
example function or event. Now, so far we've just
been costing straight to the ThirdPersonCharacter
Blueprint because that's what our character is. But because our
character blueprint, there's also a child of
the character types, so its parent class
has character. We could also costs
to character. So if I delete these
notes here for now, we'll drag out from
our overall actor and cost to the character. Will use a cost character note. And I'm just going to
add another print string here to the top pen. And this will be if our
cost succeeds, so I'm done. So I'll print screen dm will
run if our cost succeeds, and fail, will run
if our cars fails, and if we run over our box now in the world has character. You can see that Don is running because our character or our ThirdPersonCharacter
is also a character and its walls and our
character is also important. So we could go back to our
trigger again and replace this with a cost to ****. And just like before, I'll
connect the successful up to W1 and the failed up to
the File Print String. And you'll see when we
run over the box again, that it's succeeding still, because our character
is a child of the ****. Now if we go back to our
trigger and we try and access, say, our health variable
from the **** cost here. So if I drag out and didn't get. Current health, you can see that we can't
access that variable because that variable doesn't
exist in the **** class. It only exists in our
third-person character. So we can't access any of that, any of those functions
or events or variables that we created
in there via the ****. And that's the same for
our character costs. So if I drag out and
cost character again, again, we will only be able to access variables and
functions and events. They exist in the
character class, not anything that exists in
our ThirdPersonCharacter. And this is useful
because maybe you had five different characters
in your game and they all had their own
individual blueprints. You wanted your
trigger just to check, is the character overlapping me, instead of having
to have a cost for every single possible character
blueprint that overlaps, you can just do one cost node, say is it a character or does the blueprint
that's overlapping us? Does it inherit
from a character? If it does, then great, we can pass it succeed. We can set variable, and if we need to later on, we can even use this output. We could set it to a
character variable. And then later on in our
code, if we needed to, we could then cast to a more specific blueprint
so we could cause till the ThirdPersonCharacter
and we could access all of its information
like we did before. So we could do get current and we can connect this
up to our print string. So now when we overlapped a box, it will check, is the
object a character? If it is, we'll set
that as a variable. Then we'll check is the
character that we've overlapped. Is it a ThirdPersonCharacter? And if it is great, then we'll print string at its
current health. So when we overlap the box, you'd expect that their
current health will print out. So casting allows us to
cost or have children Blueprints cost to
their parent blueprint and the cost will still succeed. So I can give you
an example of this. We could right-click our
ThirdPersonCharacter and do Create Child Blueprint Class. I'm just going to call
this third person, actually just keep it that name. I'm going to open that
show Blueprint Class up. I'll select the
character mesh it and I'm just going to
change it to say, the money simple here. So we can tell the
difference between the two different
characters or compile. And also we can change the
current health value as well. So if I search for current, will change the current
health value to 25. And we'll go into
our level here, and I'll go to the windows. And we want the world settings. And this will just
allow me to change which character we're
using in the game. So I'm just going
to change it from ThirdPersonCharacter to
ThirdPersonCharacter child. It's now when we
hit play, you can see that we're now using the child character instead
of the original character. And if I run over that box, you can see that the health
is still printing out even though we're not using
the ThirdPersonCharacter. And that's because our
ThirdPersonCharacter child is a child of the
ThirdPersonCharacter. So in our trigger, when it gets to our cost
ThirdPersonCharacter, it will succeed because our ThirdPersonCharacter
child is still a ThirdPersonCharacter is just a child of that
ThirdPersonCharacter. So all of its costs
will still succeed. And if we wanted to,
we could even add custom code and variables
to our Child Blueprint. Then we wanted to access those. We would then have to cast. Or we could cost from
our other actor here, we could cost to
the child blueprint to access those variables. As an example, if I go to
my third-person child here, I'll add a new variable,
variable, not a macro. And we'll set this to, set it to a float, and
we'll call this damage. Now when we compile and we
go back to our trigger, if I just disconnect
this code for now, if I drag out from
my other actor and I do Cast to ThirdPersonCharacter. We've got our original
ThirdPersonCharacter note here. If I drag out and I try
and get that damage rally, you can see that I
can't access it because that variable doesn't exist
in the ThirdPersonCharacter, only exists in the
ThirdPersonCharacter child. So if we've needed to
access that variable, we'd need to cost to our
ThirdPersonCharacter child. So it will cost to
ThirdPersonCharacter child. And from that, we can get
damaged valley like so. We can also access that
current health value because our child inherited that value from the third-person
character blueprint. Now, another feature of costs. Notice we can change
them to be pure. So if you remember from
our functions lesson, we have impure and
pure functions. And essentially if a
pure function is run, so this, sorry, an
impure function. This is an impure function. The calculation will only
be done when it's run, and then it stores this
kind of reference in the pen so we can access
it multiple times, and this node will only run once when we
actually execute it. Now if I disconnect this node from here and I right-click, and I do convert to pure cost. And you see that it becomes
a node that doesn't have execution pins being in, plug-in or other actor here. So now, whenever any information has gotten through this cost, this cost will be run again. If I was to do print string, we print string the
current health, and we print stringed
the current damage. This cost node
would actually run twice for every output pin
that's connected to it. Whereas if we
convert this back to an impure cost, like so. Now our costs note
will only run once. It will run once when we execute it through
the execution pins. And then it stores
that reference to our ThirdPersonCharacter
child in this pen. And even though we're using
a print string twice, this cost node will
only run once. So that's the difference
between pure and impure costs. Most of the time
you'll be using NPR just because they're a
little bit more optimal. And you don't really
want a cost to be running for every single pen that you've got connected to it. Don't forget that you
can always just promote your output pin to a variable. That means that it's only
going to be run once. And then you can
access that blueprints variables in the future
without having to cost. So that's it for
our casting lesson. We will be using causes quite a bit more in future lessons just because there
are pretty cool part of coding and the engine. In our next lesson,
we're gonna be taking a look at event dispatchers.
18. Basics (Event Dispatchers): Hey everyone, In this
lesson we're gonna be taking a look at
event dispatchers. So if you were following
along with our last lesson, I had quite a few
extra blueprints and I was changing some
things in the settings. So all I've done
for this lesson is create a new third
person template. So we've got a fresh
start for this lesson. So to start with, Event
Dispatcher allows to cool code on Blueprints without
actually having to know the specific blueprint that we're calling the event on. I'm going to set up an example here so we can try this out. So I'll start by creating
a blueprint class. I'm going to set this to an actor and I'm going
to call this trigger. And we're also going to create
another Blueprint class, and I'm just going to call this. So we'll open up our trigger. And like we've done before, I'm just going to
add a collision box component and we'll compile. Then I'm going to move
my collision box up a little bit so we can
run over it and the game. And I'm going to search for hidden and untick
hidden in game. Then we're going to go
to the Event Graph. And I'm just going to
delete these nodes, right-click and search for
event begin to overlap. Like before. This event runs when
something overlap. So I'll trigger and
it gives us access to the actor that overlapped us. Now, we're gonna go to our
cube that we just created. So open up the queue blueprint. And in here I'm
just going to add a new component and I'm just
going to search for cube. We'll add a cube. I'm just going to move it
up a little bit like that. And we'll go to our event
graph and just compile. Next, we're going to
create a new variable. I'm just going to click
the new variable button. I'm going to call this trigger. And we're going to set
the variable type to the trigger blueprint
we just created. So for me that is the
trigger option here. I'll select that
and compile them. We're going to
select our trigger variable and we're going to
take on instance editable. And if you remember, that
will allow us to change this value when we select
our cube in the level. So we'll compile again, go to our third person map here. I'm just going to
add in three cubes, so I'll draw those in like this. And I'm going to add
a trigger as well. So I'll put this here. Now I'm going to select each
one of my cubes and you can see that we've got
our Trigger option here. Now. That's because when we
selected our trigger, we ticked on instance editable. So if yours isn't that you
need to make sure that that's ticked on and
then you compile. So now we can select a trigger. I'm just going to
click the drop-down and select our trigger here. So that's the trigger
blueprint here. I'll do this for each one
of our cube blueprints. And all we're doing is we're
just setting that trigger variable in our cubes to
this specific trigger. Now we're gonna go back
to our trigger and actually create a new
event dispatcher. So if we go down here and
they might blueprints panel, you can see we've got event dispatchers and
we can either click the New Event Dispatcher
button here or we can go to add and
select Event Dispatcher. So I'm just going to click that. I'm going to name this
example dispatcher like that. And we'll compile. Now, we're going to call
our Event Dispatcher whenever a character
overlaps or trigger. So I'm going to drag
out from other actor. I'm just gonna
cost to character. And that will allow us to check is the input
object or character. If it is, then we can run
the rest of our code. And I'm going to drag out from
my Event Dispatcher here. You can see that we get
a few different options. I'm going to be
checking, Clicking cool. And if we click that,
you can see that we get this node and this cause
our Event Dispatcher. Now, I'll compile and
go to our cube in here. I'm just going to
delete these two, note it and I just want to keep the beginning play node
because we will use that. I'm going to get the
trigger variable here. I'm going to drag out. I'm going to do a sign. We'll scroll down
and we want to find the sine example dispatcher. I'm going to click that. You can see that this creates
a couple of nodes for us. So it creates first
and then assign node. And it actually creates
us a new custom event. And I'll connect this up
to the beginning play. So what this
essentially does is on Begin Play, we assign, well, we use our trigger
reference here to assign our event to be run whenever the example
dispatch it is called. And if you remember
in our trigger, whenever a character
overlaps or trigger, we call that Event Dispatcher. And what this will
do is now our cubes, all three of them will run
this event when the event, the example dispatcher is called inside the trigger
that we selected. So I can run some code here. Say we could do set
location, location. We want Sac location will do get mapped to location L
plus some value to it. So we'll do an add. Now I'd say a 100 in the height and connect
up to news location. It's now when we enter
our trigger because we've binded this event. Two example, dispatcher
or trigger will cool and fun example with dispatcher and our cubes will move
up, so we'll hit play. Now, when I run over my trigger, you can see that all three of
those cubes have moved up. Now, this is helpful because
our trigger doesn't actually have to tell each one of
these cubes to do something. All our trigger is doing is
calling example dispatcher. And then our cubes are actually
set up to do something when that specific trigger
runs the example dispatcher. So that's the basics of how
event dispatchers work. Now, if you remember when we were in our trigger here and I dragged in my
example dispatcher, we've got a few
different options. So we've tried the cool node. That's what runs the
Event Dispatcher and runs any events that are assigned
to the example dispatcher. We've also got binds. So
if we create that in C, this is actually the same
node that we had in our cube. It's just hasn't created
the event for us. So maybe we already had a customer event that we
just want to plug into it. We can use a Bind node. If I drag it in again, you can see we've got unbind. This allows us to connect to an event and actually
tell it that we don't want that event to be run anymore for our
example dispatcher. So for example, if we compile again and I hit Play when I run into this cubing
and see them move up. And if I run into them again, you can see it's
adding the height. Now, maybe I only wanted
that to run once. And then after that, if the player runs
into the pupa, they won't move up anymore. And I can do that. So I
can go to my cube and I can drag out from my
trigger and do unbind. We want to find unbind all
events from Event Dispatcher, or we can use unbind events. So we'll use unbinding of them. And we can say we
want this event to be unbound from our
example dispatcher. So now this will only run once and then it
won't run anymore. So if I run into it now and
I go back and I run back, you can see that
now our event is no longer bound to our
example dispatcher. So even though it's
still being run, that event is no longer running. Now going back to our trigger, we can drag out again. And there's also an
unbind all option. Now that pretty much
does the same thing. The only difference is
we don't specify event. So if I drag out and
I do unbind all, we can unbind all from our
example dispatcher here. You can see that
there's no event input. This will just
unbind all events in all blueprints that are bound
to this example dispatcher. Now, event dispatchers
can also have variable inputs similar
to functions and events. So if we go back to our
trigger blueprint here, and we select our
example dispatcher in the Details panel. I'm just gonna get rid
of this hidden search. You'll see that
we've got inputs. And if we click the New
Parameter button here, we can add new variables. So we could add floats, booleans, any variable
type you want. I'm just going to add
a float and I'll set this to be called, say float. We'll compile. You can see it's giving
me an error here and it hasn't updated the
variable name. Sometimes this can happen with event dispatchers.
Don't worry too much. You can just right-click
the node and we'll do the refresh nodes. And you see that
it's now changed the name to what it should
be and we can just compile. And now we have no errors. Now that's added
this variable input to our cool dispatcher. If we go to our cube
now and compile, you can see that it's
actually automatically added that float variable
to our event here. Now, whatever we set in our Event Dispatcher
is what will be output here in our event. So if I, for example, wanted this to be five, and I went to our cube, I'm just going to do,
I had a print string. So I'll just add a
print string here. And we'll connect the print
string to the float value, which moves these
along a little bit. So we've got a bit
more space like that. Now, when this event runs, it will print out whatever
value our float value is, and that's set by our
Event Dispatcher. So if I compile it play
and I run into my cube, you can see that all three of these cubes are
running the code, so it prints strings 53 times. Now, the cool thing about event dispatchers is
we could have lots of other blueprints
that are also using this Event Dispatcher
that we've just set up. So that maybe when a
character enters a room, you have a trigger that
they walk through. And maybe you wanted that
room to change in some ways. You wanted some
objects to disappear. You wanted some objects to move, maybe, maybe a sound to play. You could have all of that
stuff happening using just one event dispatcher that runs when your character
overlaps a box. Now heading back to
our trigger blueprint, if you remember when we select
our Event Dispatcher here, we also have an option called
copies signature from. And if I click that, you can see we've got a few
different options. Now, essentially this
just allows you to copy the input variables of
another event dispatcher. So there's a big list of
them here because the engine actually comes with a bunch of event dispatchers built-in. So this is just useful
if you wanted to, instead of having to manually
add variable inputs. Say you had an event dispatcher already with the same inputs
that you want to use. You could use Copy signature from and just add
those straight away. Now, to give you an
example of some of the event dispatchers are
actually built into the engine. We can right-click
and search for bind. And if we scroll through it, you can see that we've got
some built-in bind events. So for example, we've got
some for mouse inputs, we've got some for damage, and we've also got
some for collision. You can actually
see that there's a Bind Event to on
actor begin to overlap. That's the same as
our event here. So we could actually set
this up differently. So if I click Bind event too. On acts or begin overlap
will get a game play node. Connect this up to here. Now we can actually delete
this event and create our own custom event that will run whenever an actor overlaps, I'll trigger using
this Event Dispatcher. So I can right-click
or I can actually drag out from the event
here, search for custom. You'll see that it's just made an event for us
and it's actually added those overlap actor
and other actor here. So I can call this, say. And now we can connect this up. We can take the other actor pin, plug this into our
character check. So now essentially what this code is doing
is on Begin Play, we bind an event, which is our overlap event here, to when an actor begins
overlapping our trigger. And then when an
actor does overlap, I'll trigger or overlap
event will run. It will give us the other actor. We can check is that other
actor that's overlapping, I trigger a character. If it is, then we call it
our example dispatch up. We can test if this is working, so we'll just compile
and save, hit Play. And now when we're
going over our trigger, you can see that that code is actually still
running like before. But instead we're now using an Event Dispatcher
that's actually built into the engine. Now, so far I've only
actually been using the Event Dispatcher to cool
events on another Blueprint. So for example, a cube here runs this event When example
dispatcher is rum, but we can also use our Event Dispatcher
within the same blueprint. So maybe I wanted an event to run when I call my
Event Dispatcher, actually inside my trigger,
I could do that as well. So I could drag out
my Event Dispatcher. I could do, if we
click Assign here, it does the same thing
as the Bind event, but it also creates
our custom events. So if I click assign, you
see that it's created our Bind event and
the customer vent. Whereas if I drag
out and do bind, you can see that it
just creates the bind. So that's just a click away, basically creating the two nodes together. So we can do that. I can connect this up here. And I'll move my this event up here in c that gives
us a float output. Because if you remember,
we have a float input on our example dispatcher. Cool. And we could run some
code inside our trigger, and that will run whenever our example
dispatcher is called. So I could add a print
screen here, say hello. Now, when we run onto our cube, you'll see that it prints
the five values for R cubed. And then it only runs once. Hello, because we only
have one trigger and that code is being executed
inside our trigger. Now, something to
keep in mind with these events, dispatches is, if I have a custom
event already, say I'll create a
custom of them, and maybe it has
different inputs. So I'm just going to
add a float input. If I tried to connect this
up to the Event Dispatcher for on actor begin overlapping and see that I
can't actually plug it in. If I disconnect this, you can see that I
still can't plug it in. And that's because this
custom event doesn't have the inputs or the outputs. This binds node requires. So any customer event that we plug into has to have
these two variables. So I can't connect this to this. I can connect it up to our
example dispatcher like this, because it's got a float
value and that's what's required, for
example, dispatcher. So normally the easiest way if you just have a Bind event, say like this, is
to just drag out, search for Customer them. And it will create a
custom event for you. And it will add any of the
variables that you need it to have to be able to
connect to that dispatcher. Now, as you can
probably imagine, if you had a lot of these, you'd get these long wires going all over the place and
it could be a bit messy. What you can do
instead of having to run the wire to the event here, she can drag out and you can
search for Create event. And you get this little note here that allows us to
select another event. So we can click this and you can see that it's only
giving me the option for customer vent underscore 0 and example dispatcher
underscore event. And it's only giving me those
options because they're the only events that
have our float value. And I can say select will select our example
dispatcher of them like that. Now you can see
that our red wire isn't connected up to
this event anymore. But I'll hello string watch, they still run because this Create Event note here basically connects the Event Dispatcher to the event up here without
actually connecting a wire. So if we compile it play, I'm running into
our trigger here. You can see that our Hello print string is still
running even though it's not directly wired
to that Bind node. Now that create an event
node actually allows us to use functions with event
dispatchers as well. So if we click on the
drop-down option here, you can see that we
can set it to none. We can also create a
matching function or event. If you click matching event, it will just create a new
custom event down here. And it will add the
appropriate variable outputs that the Event Dispatcher needs, and then also just automatically set it to that new event. So now when the events batch runs are accustomed
to event will run. But we can also create
functions that it will cool. Instead, we can click Create a matching function and that
creates us a new function. This is just a normal function
like we've used before, is just that this
one will now run whenever our example
dispatcher runs. So you can see that it's automatically added
a float for us. This will run like a
normal function one. So we could add some code
to this if we wanted to. I had a print screen. Now to put this to function, we know that it is this
print string that's running. And now when we hit play, I run over my trigger here. You can see that keeps them moving as printing
those five values. And it's also printing
function because that function inside our
trigger is now being run because it's set to be bound to the example dispatcher. So that's it for our
event dispatchers lesson. There are a great tool
for being able to call one event and a
blueprint and effect lots of other blueprints and different ways without having to specify each blueprint
that you want to effect.
19. Basics (Interfaces): Hey everyone. In this
lesson we're gonna be talking about the
Blueprint Interfaces. Blueprint Interfaces allow us to call functions and events on other Blueprints
without having to cost to that blueprint type. Now you may have noticed
that I've still got the cube and trigger blueprints
from my previous lesson. I'm just going to keep
those because I'm going to reuse them for an example
a little bit later on. So to get started,
we're going to create a new
Blueprint Interface. If I right-click here and
go to the blueprints, pop out and we'll go down
to Blueprint Interface. I'm just going to
call mine BP on score example
interface like that. And we'll double-click
it to open it up. And I'm just going to drag mine and add it to the tab up here. So as you can see, we've
got a new user interface. We've got this large event graph that we're actually not
going to really use it. We can't make any
edits here or add any code is just a preview of
the functions that we add. And you can see we've got
our functions tab over here where we can create
and delete functions. And if we've got a
function selected, we can add inputs and outputs. So we'll start by renaming the default function that comes with our example interface. So I'm just going
to rename mine to decrease health like that. And we'll compile and we'll
come back here in a moment. But I want to show you how the decrease health function looks in our
character blueprint. So we'll go to the
ThirdPersonCharacter. I'll right-click and I'll
search for decrease health. And you can see that
this comes up or decrease health message node. Now, because we've created
this in our example interface, this will appear
in every blueprint if we right-click
and search for it. So if I create this, you
can see it looks a lot like the cool node that
we use with the events. With a couple of differences. We've got this icon in the
top right hand corner, and we've also got
the target input, but it doesn't say
self next to it. We actually have to
provide a target. And this is just the, the blueprint or
the reference to the blueprint that we want to call our decrease.
How function on. Now, if I was to
run this node now, so if I get the Plano and I connect this up to
a decrease our function, nothing would happen because we haven't provided a target. But if we drag out and
do self as a target, nothing would happen still, because we haven't
actually implemented this function into our
third-person character. So to do that, we need
to just compile first, we'll go to class settings. And under Implemented
Interfaces, it says no interfaces currently, but we
can add a new one. So we'll click Add and
we'll search for example. And we'll select the
example interface there. And then we'll compile. Now if we go down to the
interface is option a, you can see that we've
got decrease health. Now, if we double-click this, it will actually create
a decrease health event. Now, when we run, when our Begin Play
runs and it runs this decrease health cool node
with our self as a target. This event down here will run. I'm just going to
move it up closer to our beginning play node here, which move up here like that. So we can test this quickly. I'll just run a print
string and we'll hit play and see that that print screen and we've
just added is running. Now we can also add
inputs and outputs to our interface functions. So if we go back to
the example interface, select our decrease health. I'm going to add an input first, so I'll add a new input. I'll leave it as Boolean. And I'll just say this is, we'll just call it
a test for now. You can see that the
preview is updated. It says test will compile and get back to
our ThirdPersonCharacter. And you can see now that
our cool note here, the decrease health interface function recall node has now got a test input and our
event has a test output. So whatever our test input is, that will be the output
for our event node. If I take this on and I plug
this into our string here, when we hit play,
you will see it will print string true, true. Now, we can also add outputs to our example
Interface function. So if we go to that, I'm just
going to press escape to accept the plan editor will
select decrease health. And down here, we can
add a new output. So I'll add an output. There's a bug right now where right now it's all
gone, grayed out. I have to compile, then select the decrease
our function again, you can see that I
can now rename it and access this information. Maybe by the time
you're following this lesson, that will be fixed. But for now that's what you
have to do. Four outputs. I'm just going to name this
current health like that. And we'll set it to an integer
and we'll compile this. Now adding outputs to an interface function
will actually cause some changes in our
character blueprint. So if we go back
to our character, you can see that our
event node has now got a warning on it
and it's actually converted itself to a customer, then it's no longer an interface events so
far as to hit play now. And you can see that
our print string is no longer running
because that event isn't actually being cooled. And if we go to our decrease health care and double-click it, you can see that
it's actually taken us to what looks
like a function. Now, it hasn't added
our output node. We can add that just by
right-clicking and doing return. We want add return node. And you see that
it's now giving us an output execution pen with
our output current health. Variable. You might not have to do that. It might just automatically add the returned node for you, but sometimes it doesn't. So if it doesn't, then you
can start it yourself. So now this function will
actually run on Begin place because we're still calling the decrease health
interface function. So if we connect this
up to our output, now, maybe I want it to output
a current health value. So we'll create a
new health value. Health. We change
this to an integer. I'll compile, I'll
set this to a 100. Now because this is a
decrease how function I've called it will make it
decrease by some amount. We'll do subtract and
we'll do Set Health. Now. We'll subtract five from our health and then we'll output the current health value. As you can see,
you can just write code in here like
a normal function. It behaves just like functions
that we've used before. So now if we go to
our event graph, if you remember on Begin
Play or decrease health, interface function
is gonna be cooled. We've got tests ticked on, but we're not doing
anything with that and decrease how function, as you can see, it's
not plugged them. And then we want it to return
a current health value. And I can add a
constraint to this, which started print string here. Now are decreased health
function that we had earlier. This isn't doing
anything anymore. It's just been converted
to a normal customer, then we can actually
just delete that now. And if I can pull
and I hit Play, you can see that
our current health has gone down by five. It started at a 100
and that's now 95. So you might be wondering what
the point of interface is. We're just using these
normal events and functions. Now, the cool thing about
them is we can use them in other Blueprints
without having to cast to say
first-person character. So what I'm gonna do is I'm
gonna go to my trigger here. And I'll go to the
Event Graph now, this code is from
the previous lesson, so I'm just gonna
highlight and delete that. Also going to delete
this function as well. And we'll just compile. Now normally if I
wanted to say decrease my health value and my
ThirdPersonCharacter, we would create an event, begin overlap or
begin actor overlap. And that runs whenever
something overlaps, I'll trigger and it
gives us access to the actor did
overlap our trigger and we would cost to the ThirdPersonCharacter like we did in our casting video. Then we would either
get our functions, say I decrease health function, or we would get our
health variable. Then we would
decrease it and set the new value using
our car snowed. But what Blueprint
Interfaces allow us to do is instead
of having to cast, we can actually
just drag out from other actor and
we can search for a decrease health
interface function and create that and
that'll be our target, whatever overlaps I'll trigger, we'll call the decrease health function in
that blueprint. And this will only actually run in that blueprint if we've implemented the
interface like we did in our ThirdPersonCharacter. You remember, we set
the interface and here, if an object that doesn't use RPP example
interface overlap, so I'll trigger, this
code will still run, but just nothing will happen. We won't get any errors, we
won't have any problems. This will just be ignored and then the rest of
the code will run. Now because our
ThirdPersonCharacter does use a decrease how function when we do overlap
our trigger, it will be run. So if we go to our
third-person character here, I'm just going to
open up the decreased cell function and I'll add in, or actually we'll go back
to our trigger here. We'll add a print string
and here instead, so I had to print a string and we'll print out
our current health. And because our characters, what's going to
be overlapping or trigger it will be
decreasing their health in our character and then we'll get our characters current health
so we can compile it play. Now when we run
over our trigger, you can see that our
health decreases. Now the good thing about
this is we're not limited to just doing this in our
ThirdPersonCharacter. If we wanted other blueprints, say a vehicle for example, when it hits this trigger, we want to reduce
its health as well. We can do that. So if we open up our
cube blueprint here, for example, I'm
just going to delete this code from our
previous lesson. We add a health variable. We'll say it to an
integer as well. And we'll set the
value to say 50. Now, right now, if
our cube was to overlap our trigger hair, nothing would happen because
our cube doesn't have the example interface implemented.
So we'll do that now. We'll add the example
interface and we'll compile. Now, as you can see, decreased health function is now in
the Interfaces tab here. But if I was a cube was to
overlap our trigger, now, it's still wouldn't do anything because we
actually haven't added any code to the decrease health
function inside our cube. If we open that up, just
by double-clicking up, you can see that we've
got our return node and r note here. And we can run code. So if I wanted to, I could do health. We'll do minus. And we say, well minus five. And then we'll set and we will return the
current health here. So now when our cube
overlaps are trigger, this function will run. It will take the current
health value minus five, set the current health
value, and then return it. So if we hit Play, if I run over it
with my character, you can see it's still
decreasing our health value. But if I press F8,
which basically stops me controlling my character and allows me to move about freely. But the game is still running. I can select my cube if I
move it into the trigger, you can see that when
it enters the trigger, it's actually printing out its health value and
it's also decreasing it. So hopefully that gives you an idea of how Blueprint
Interfaces work. They essentially allow us to
create functions that can be run in different
blueprints without having to cost to
those blueprints. And that's useful in use cases like our trigger here
where if you want a Trigger box to damage anything that goes
in it that has health, then you can set that up
using Blueprint Interfaces.
20. Basics (Components): Hey everyone. In this lesson we're
gonna be looking at the component blueprints. Now if you're following along
with the previous lesson, all I've done here
is just create a new third person template. So we've got a fresh
start for this lesson. So to get started, we
use components to add new functionality to
actor blueprints. So for example, in
our level here, if I select the
ground, for example, and over in the Details panel, we have the components tab that shows us what
components this actor has. So we can see that it has
a static mesh component. And that's what allows
us to actually set a static mesh to display in
the world for this actor. Now, there are a lot of
different types of components. So if I go to my Character
Blueprint for example, and we go to the viewport. You can see over in the
Components panel we have a few different types of
components here as well. So to start with, our character
has a capsule component, which is this capsule
shaped collision area. And that's what stops
our character from just falling through the ground or being able to walk
through walls. Then we've got an
arrow component, which basically
is just set up to point in the forward
direction for our character. We've got the mesh component, which is a Skeletal
Mesh Component. And that allows us to
set a skeletal mesh. And the Skeletal Mesh is just a mesh that
can be animated. Then we've got our camera boom, and camera that's attached
to the camera boom. And the way it works is if between the end of the camera boom and the
start of the common brim, There's an object blocking
that it will get shorter. And because our camera is attached to the
end of the camera, boom, that will bring our
camera closer to the character. If there's an object
blocking our camera, boom. Then we have our camera. And our camera is just
what allows us to choose the perspective that our player sees when they're
controlling this character. Now, all of the components of explained so far are
seeing components. These are components that
can exist in the world. They have a location
and sometimes they have a visible objects to them. But we also have a
different type of component which is
purely just code. They don't have a location. Then example, if this is our Character Movement
Component here, which comes built
into the engine and built into our
character blueprint. And if we wanted to, we could add this component
to other blueprints as well. And this is what handles
our character's movement. The important difference between a sink component and
a standard component is that a standard component
doesn't exist in the world, doesn't have a location and can't be visible to the player. Whereas seeing components
can exist in the world. They have a location
on a rotation. And some of them like our
mesh component, for example, does have a physical
object in the world. Now, the reason
we use components instead of just putting
all of this code and functionality straight into
a blueprint actors blueprint is because we can
reuse components on multiple blueprints that can save us a lot of time having to write code over and
over again or copy and paste it when we could just
do it once in a component, then reuse that component
in multiple blueprints. Similarly to how
functions are useful, because we can change
code in one place and it affects it in all of the places that
function is being used. If we change the code inside
our component blueprint, the blueprint that's
using that component will also be updated and
get those changes. We can create our own
Blueprint Components. All of the ones we've looked at so far are built
into the engine. If you click out, you
can go through and see all of the components
actually come with the engine. But if we want to
create our own, we need to go to the
Content Browser. We'll right-click and
go to Blueprint class. And then here you can see
at the bottom we've got active component
and sink component. Now if you remember from full scene components can
exist in the world. They have a location, whereas active components don't. They're purely code. We'll start by creating
an active component. I'm just going to call
this VP to underscore actor component like that. And we'll double-click
it to open up. Then I'll just drag
the tab up here to the top bar with
the blueprints. Now, you may have noticed
this UI looks a little bit different from our
normal blueprint editor. And as you can see, we don't have a Components
panel because components can have their own
components. Only actors can. We also don't have a viewport because this is an
active component. It doesn't have components
of visible parts to it. So it's purely code. So we only have access
to the code relevant UI. Pass those differences. There isn't much
different to coding and a component then computing
and coding in a blueprint. We have our beginning
play node or node, for example, these are
just here by default, but we can access most of the events and functions that we can in our normal active
blueprint inside a component. Now, because this is
an active component, I can't do something
like say get location and we can't find getLocation
node because this actor, this sorry, component,
doesn't have a location. So I can give you an example of how we can run code
and I component. Now, if I drag out from
my big in play here, I'm just going to
add a print string. So I've added some
code to my component. And if I can poll and hit Play, you'll see that nothing happens. Now, that's because I
haven't actually added my new active component to any blueprints that
exist in my level. So that code isn't gonna be run. But if I go to my
ThirdPersonCharacter here and I go to add, and I search for
actor component. You can see we've got
our BPR, its component, that's when we've just
created or add that. And you can see that it's
actually added it to this second half of the panel along with
the character movement. That's because these are
both just active components, not seeing components. But now if I compile and we go back to the play and editor, you can see that now
that code inside our component is actually
running because it's now attached to
ThirdPersonCharacter and its begin play will run when the
third-person character is spawned or when
the game starts. Now we can also access
functions, events, and variables from
our active component inside the blueprint
that we added them to. So if we exit out
of play an editor and I go back to my
active component here. I'm just going to add
in, say, a new variable. We'll just call this Test. I'll create a new
function as well, and we'll call this
example function. And I'll also create an
event or create an event, I'll just call this example. So now we've got our event, function and variable,
and these are all inside our actor component. Now if I go back to my
third-person character here, I can access those variables
and functions really easily just by dragging in my BPS component from
the Components panel. Drag out. And I can just
search for test, for example. And I can get all set that
test variable if I want to. I can also access
the functions so I can drag out and
search for example. And you can see I can
access my example function and my example event. Just like that. Now a good example of a
system that you might want to put in a component is
something like a health system. And the reason for
that is you may have multiple actors in your game that you wanted
to have a health system. Now, instead of having
to add a variable and functions that
affect their health to every one of those actors. We could just create
one health component and add that health component
to the multiple actors. Then, because we can just access the functions
and variables from our component easily inside
any blueprint we add it to. We could then use that health
system without having to recreate all the functions and variables inside the blueprint. Now, we can also access and actors components from
other blueprints. So if I quickly put together
a trigger blueprint, I'm just going to
create a new blueprint. There'll be an actor. I'm just going to call it
trigger will open that up. I'll add a box
collision component. Box collision. We go, I'll move this
up a little bit. And I'll turn off
hidden in game. And then we'll go
to the Event Graph and delete these nodes. And I'll create a
begin over lap. If you remember, this node runs whenever
something overlaps, I'll trigger and
it gives us access to the actor that overlapped us. So we can access our component from our ThirdPersonCharacter
and a few different ways. If I drag out from other
actor and search will cost to the person. We've now got our costs node, which if you remember, we've
done a separate lesson on. And if we drag out, we can access this. Or I'll third-person characters, variables, and functions. But we can also access
its components. So if I search for
actor component, we scroll down that usually at the bottom here you
can see I can get our active component that
allows us to access any of the functions and variables from our x-component through
our ThirdPersonCharacter. If I drag out when
I search for tests, for example, gets
test, there we go. I can access that variable. I can also access if I
search, for example, you can say I can access my example event and
my example function. Now, there's another
way we can access our actors components
without casting. And we can do that using a node that if we drag out
from our actor, will search for
component by clashing. See up here, if I
create that node. Now essentially what
this does is it takes an actor input and we set a component class so I can search for actor component. And I will set this to
the BP act component. That's the one we created. This will check, does our actor input have
this component? If it does, then it will output a reference to
that component here. And if I drag out, I can search again just from
my test variable. I can also access those events
and functions we created. Now, if r does not have
an active component, then this reference
won't be valid. So what we do whenever we
use this node is just make sure we use and is
valid node like that. So now, when an object overlaps are trigger, this
event will run. It will check, does this actor
have our bp act component? Then if it does, we'll
output a valid reference. So R is valid, would run valid. And if it doesn't, then is valid node would
run, is not valid. Now we can actually
have multiple of the same component
in the same blueprints. So if I go to my third-person
character here and I add the BP underscore
app to component. Again, you're going to see
that I now have two of that component in my
ThirdPersonCharacter. Now we may want to access
those using a node like this. So we can delete
this node instead, we can use the Get
component by class. And that is a node that works pretty much exactly the
same as our previous node, but instead of a single
variable output, it's an array. Now, if we were to search for BP unschooled actor component, this would return
every single component that matches our component
class from our character. And it returns it in an array. And if you remember
from our arrays video and re just allows us to store multiple of
the same type of variable all in one variable. And if we wanted to access one of those variables
from our array, we would need to drag
out and user get node. We need to supply an index. So this is which variable within our array
we want to access. And then from our get
node we can just drag out and search for,
say, gets test. And because this pen here
is a BP act component pen, we can get our test
variable or we can get those example function and
event we created earlier. So that's just a few
ways that you can access a actors components
using these nodes. Now another cool feature of components is we
can actually set their variables
for each blueprint we add the component to. So if we go to our app
component blueprint here, I'm just going to create a new variable and I'm
going to call this say max health. Like that. We'll set it to an integer. Now if we compile
this blueprint and go back to our
ThirdPersonCharacter Blueprint. I'm just going to delete
this extra active component and I added was
like the first one. And you can see over
in the Details panel, we have a default category. And then here we've
got our test variable. That's the Boolean we
created at the beginning. And we also have our
max health variable, and we can use these to set those starting values will
be for our app component. So I could set
this to say a 100. And maybe I had a second
character blueprint. I'll just use the
trigger as an example. So if we add another
BP underscore, BP, BP act component, you don't need to
use underscores. And here you can see if
I use an underscore, it doesn't find it. So if I do BP x component and we get rid of this searcher, and I select that component. You can see that we again,
we have our test and max health variables here and
the default category. And you see that it's
defaulted to 0 by default because
that's what it's set to inside our x component. Then in here, we could set
this to be say, a thousand. Now, if we set up on Begin Play, we'll print out our max health. For example. We put our trigger and the
level and we hit Play. You can see that it's printing
a thousand and that's our trigger doing up a 100, and that's our characters
act component doing that. Next, I just wanted to
show you how we can quickly create a sink component. So we'll just exit out of the planets to right-click
and create a new blueprint. And instead of active component, we're going to click
seen component. I'll just call this BP
underscore seen component. And we'll double-click
that to open it up. Now as you can see,
it's pretty much the same as our active
component blueprint. The only difference is
in our class default. So you can see that
we actually have a location, rotation and scale. And if we go to our
ThirdPersonCharacter here, add a new component
and then we'll add our bp seen component. You'd see that we have
a location in the, in the Viewport here. We can move it around. If we select the
component in there, you see I can move it around, I can position it, we can
rotate it and scale it. And if we go back to
our sink component, because it's the same component, we can access its
location so we can search for gets wild location. You can see we've got our
Get World Location node. We also have our
get's world rotation. If I spell it right,
rotation that we go get world rotation. And these work the same as our nodes in our
active blueprints. It just gets the location and rotation of our sin component. Now, so far we've
only been adding components using the
Components panel here, but we can also add components during gameplay using code. So if I right-click here and my ThirdPersonCharacter
Blueprint, I search for begin play. If we drag out from parents, search for add and then the
name of our components. So BP, you can see that
I've got options for BP x component and our
BPC and component. So if I click our
x component here, we get at this node. And this essentially
means that on Begin Play or when
our character spawns, it will add a new BP act
component to our character. We can use the return value
here like we could with if we drag in a
reference like this, we can just drag out and
search for, say, get, test for example, we can
access our variable. We can also access those example function and the event that we
created earlier. And if we wanted to, we could create a variable to
store this reference. So if we wanted to access this new variable later on in
our code, we could do that. We're just promote a
variable that creates us a new variable that sets
a BP acts component type. We can name this to
say new computer. And that allows us now to access that new component we created later on, then we can use it. So it gets a maximum value. When selecting
this add BP actin, HE can actually see that we get access to it starting variables. So we could set our max self to whatever we wanted to say 99. And now when that act has created its max helpful, benign. And lastly, we can also destroy components
during gameplay. So if I drag out my active
component reference here, just going to delete this code. Now to destroy component, we need to do is drag out, search for it, destroy. You can use the destroy
component node and that will completely remove the component from the blueprint
during gameplay. Of course, it doesn't actually
affect the blueprint here. So it's not like
you've deleted it, it just destroys the component during that game-play session. So that's pretty much
it for components. Hopefully you have a better
understanding of how they work and what
they're used for now.
21. Basics (Player Controller): Hey everyone. In this lesson we're
gonna be taking a look at the player
controller blueprint. Now at play controller,
blueprint is created when we hit play
and start the game. And it's created for each player that exists in the level. And the purpose of a player
controller is to take control of a blueprints like
characters or vehicles, and provide them with the inputs that the player is pressing. Now the player controller
stays the same for each player unless a
new level is opened, in which case the old
controller is destroyed and a new one is created for when
the new level is opened. Now in the third-person character template that
we have opened here, it doesn't actually include
a blueprint controller. And that's because by
default it just uses the built-in player controller that comes with the engine, which is coded in C plus plus. So you won't find the player controller in
our blueprints panel. If we open up our game mode, we can see where we can actually set our player controller. So if we go down
and the classes, you can see we've got the
plague controller class currently that's set
to play controller. And that's our C plus plus player controller that's
built into the engine. You can also see we've got the default Pawn
Class down here, which is set to our bp
ThirdPersonCharacter. And essentially what
a game mode does is it tells the engine we want to start every player off in the game with this
player controller, which currently is the C
plus plus player controller. And this character, which is our ThirdPersonCharacter
that we've been working in, in previous lessons. But we can actually create our own player
controller blueprints. So to do that, I'm going to
close my game mode for now, and we'll right-click the content browser and
go to blueprints. And we're going to select
player controller. And we'll name this BP
example, control like that. And we'll double-click
it to open it up. And I'm just going to drag the top here up to the top
with our other blueprints. Now, I'll play controllers. Blueprint looks pretty much
like an act of Blueprint. And that's because it
is actually an actor is just a child of the player
controller as well. So in the Viewport
here you can see that, but we don't have
any visible objects. Typically you won't
be adding things like a mesh or anything like that to a player
controller's viewport. We also have a camera here. Now, this camera is only used when we're not possessing
another Blueprint. So when we possess are
third-person character, for example, we actually use the camera that's
included with that. If we want possessing
any blueprints, Then this camera is used. There is also a few
additional settings in the class defaults exclusive
to the player controller. So we've got things relating to the mouse cursor and
touch events for mobile, as well as some camera management
tools up here as well. And if we head over
to the Event Graph, you can see that
we've pretty much got the default layout
that you would expect. Now what you might be wondering, what is it that we actually use our player controller forum, what would we code
in here instead of just coding inside
our character? Now, because I'll play
controllers stays the same no matter what
character we're controlling, we can store information in
here that we want to keep the same for controlling
different things. So for example, if you had
a mission system and you wanted your missions to be
available all of the time, no matter if you're possessing a character or a vehicle
or some of the thing, you would probably want to store that information inside
your controller, either directly by
creating the code inside the controller or by adding components
to that controller. Another thing that controllers
are useful for is adding inputs that you want to stay the same no matter what character
you are controlling. So an example of this
would be if you had, say, an escape menu in your game where all your
settings and controls, or you'd probably
want that button to work no matter what character
you are controlling. So instead of doing
or adding that code into every single
character blueprint, we can add at once
and the controller, and that way input
will always be available to the player no matter which character
they're controlling. So to give you an
example of what I mean by the
information stays the same no matter which
character we're controlling will
create a new variable. And I'll just call
this mission one done. And we'll leave it as a Boolean. And I'll compile. Now, I'll go back to the content browser and
we'll create a trigger. This trigger will set that
mission one Boolean to true. So we'll just create an actor. I'll call it mission trigger. Like that. We'll open that up. I'm going to add a
box collision just so we can overlap our actor her. I'll move it up. Now set it's hidden in game
to false so we can sit. And then in our event graph, I'm going to use the
actor begin overlap. And if you remember, this will run when
something overlaps our trigger and it will tell us which actor overlapped it. So it will drag out from here, I'm gonna do a
cost to character. And from that, we can drag
out and do get controller. And this gives us
access to whichever controller is controlling
this character. Now, this will either
be valid or not valid. So if a character isn't
being controlled, this will return
and not valid pen. So we want to create
an is valid node. This way, if a character
that isn't being controlled, overlaps are trigger, we
won't get any errors. So then from our controller, we need to get our
mission done variable. So if we drag out
and research would get the mission done, it won't work because this is just a controller
object reference, not a reference to our
actual example controller. So what we can do is because
our example controller is a child of the controller
type we can drag out, we can cast to example, controller will connect
this up to is valid. And then from that we can
drag out and we can do set mission, one done. And we can set this to true. So just to go over this, when an actor overlap. So our trigger, we check is
that Act where a character, if it is, then we get as controller and
check, is it valid? So we basically check, is this character actually
being controlled by something? If it is, then we check, is this controller a
BP example controller? If it is, then we set that BP example controllers mission
one done variable to true. Now we want to be able to access information to see if our
mission has been done. So we'll go to our ThirdPersonCharacter and
then the Event Graph. I'll add a new inputs of them which search
for input event one. And this will just run whenever I press one on my keyboard. Now, we can get
our controller the same way we did in
the mission trigger. So I'll search for
it, get controller. And using this node, it will check self
for a controller. So we're in the
ThirdPersonCharacter, the self-employed as a ****
and our character is a poem. So we can check
ourselves if we have a controller will do cost to the BP underscore
example controller. And from that we can get
our mission one done. And we'll just print a string
whether or not it is done. We'll use a print string node and connect this
up to in string. Like that. I will
just compile this. Now we'll go back to
our third person map, and I'm just going to add the mission trigger
into our level. I'll make it a
little bit bigger, so I'll just use the
re-scale tool here we go. And there's one last thing we need to do before
we test this out, and that's change
our controller. So currently in third
person game mode, if I open that up, you can see that the
player controller is still set to player controller. We need to change this now to
our bp example controller. Now, because that controller is a child of the
player controller, it will do everything that that player controller
does by default. Bell also now have our new
variable that we added. So if I hit Play,
if I press one, you can see that it's
printing out false. But if I run into
my trigger, now, when I press one, you can
see it's printing out true. So this is how we
can set and get information from OCT
players controller. Next, I'll show you
how we can actually change which character
we're controlling. So to do this, I'm
going to create a second trigger blueprint. So we'll right-click and do Blueprint class
would do an actor, I'm going to call
this carrot change. Character. Trigger. Will open that up and
we'll do the same thing. We'll add a new collision
box, will move this up. I've set this to its
hidden in game to false. And we'll compile it and
go to the Event Graph. I'm going to use the
beginner actor overlap here. So to start with, we'll control another character that
I placed in a level. I'll go to the third
person map here, and I'll just drag in a
ThirdPersonCharacter. I'm over here. Then we'll go back to our
change character trigger here. And we'll drag out
from other actor and we'll cast to
character again. From that we want to
get its controller will do get, gets controller. Then we're going to drag
out from Get Controller and search for possess and
use the process node. Now, you notice I'm not casting to my BP example controller. And that's because
we don't need to, because this possess
event exists in the player controller that is the parent of our
example controller. So there's no need
to cast to it. We can already access it. And we'll connect this
up to our cost node. Now, this allows us to
take control of a pump. So what we'll do is
we'll drag out from input and will promote variable. This will create a new
**** variable for us. And with that point
variable selected, just gonna get rid
of the searcher. And we'll take on
instance editable. So that way when we select
our character, change it, change character trigger and
then level will be able to select a point control.
So it will just do that. Now, I'll drag in my
change carrots trigger. I'll put it over here and I'll make it a little bit
bigger as well like that. Now, in my details panel
over here, under default, you can see in ****, I can select a point
control and I would just pick our
ThirdPersonCharacter. So that's the character
over here, like that. And now we can go back to our change character and make sure that's compiled. Now we can test this out, so we'll hit play. So we've got our
normal character like before we can run around. If I run into my mission
trigger and I press one, you can see that this
is now returning true. But if I run into my
change character, you'll see that now we've taken control of this other
character over here. You see our old character over there still running around. If I press one, you will
see that our mission variable is still true even though we're controlling
a different character. That's because our
player controller is still the same blueprint. It was. When we are controlling
that character over that. Now we can also take control of characters that have been
spawned during gameplay. And to do that, if we go to our change character
trigger here, we're going to delete this
poem variable for now, because we're gonna
be creating a newborn using the spawn active
from class node. Now, we'll go more into detail about using this
node in the future. But essentially, it
allows you to create new actors and the
level during gameplay, we get to class. So this is the blueprint
that we'd want to spawn. So for us that's gonna be
the ThirdPersonCharacter. And we get, say,
a spawn location. So I'll drag out and
search for make. We don't want that
one, sorry, we want make transform like that. And that allows us to set
a location and rotation. We need to provide a location for our characters to spawn up. So I'll just do get
back to location now. We'll drag out from that and
do an add node just to add some distance between
our character spawn and change
code to trigger. So I'll add say 200 and the Z and maybe 400
and the X like that. So that tells our character where we want it to be spawned. And then we have this
return value and this gives us a reference to the new character that
we've just spawned. Now because our character is
a child of a character type, and characters are
children of the pawn type. We can plug this straight into
the important option here. So now when I compile
and hit Play, we can run into our change character trigger and
you'd see it spawns, I say new character
in at their location. We said we've taken
control of that character. So that's how you can
spawn new characters in and take control of them
with your player controller. Now what you may want to destroy that leftover character that when I no longer controlling. So what we can do is go back to the character
trigger, an inherent. We need to do a few more things. So first we need to store a controller variable reference. And the reason for that
is if you remember, this is a pure function. Pure functions will run
every connection they have. Now, if we try and destroy our character before we spawn
a new one and possess it, what will happen is when we
try to possess it or get controller node will run and it will use the
target of a character. But if we've destroyed
that character, then it will no longer
have a controller for us to use to possess
the new character. She's a little bit hard
to get your head around, but we'll, we'll drag out from get controller and will
promote it to a variable. We'll call it
overlap controller, like that, which
connects up to here. So now we're just
storing a reference to the controller as soon
as we overlap it. And we can actually disconnect the target now from over here. Then from our overlap controller
we can just drag out and do get controlled ****. This note just allows
us to get a reference to whichever pawn our
controller is controlling. So we can drag out from that and we're going to destroy it. Because this is
still a reference to our old character that
we no longer one. So we can do that. Then we take our
overlap controller variable and plug that into
the target of our possess. So your code should
look like this. And we can compile this. So now when we jump into
the level and hit Play, if I run into my
trigger now you can see that I've spawned
a new character. I've got control of it, but old character that we run
into the box width is gone. And if we do it
again, you can see that we spawn another character. That old character
has gone again. So that's the basics
of how you can spawn in new characters
and destroy old ones. Now, there's one other
note that I want to talk to you about and that's
the unprocessed notes. So if you go back to the
change character trigger here, I'm just going to
delete this code now because we don't
need that anymore. And we can actually get rid of this overlap controller because we don't need that either. Now when we drag out
from the controller, you remember this
The possess node. There's also the
unprocessed node. So if we create an
unprocessed node, it's essentially just
tells the controller to stop controlling
whatever character, vehicle, any **** that
it's controlling. So if we connect this up now, when we hit that collision box, we're going to lose
control of our character. So when I run into
that, you can see that my characters stuck
running on the spot. I can't control it. I
can't move my camera. And that's because
we've no longer controlling this character or
any character in our level. That's gonna be it for our
player controller lesson. Hopefully you have a little bit of a better understanding
of how they work.
22. Basics (GameMode): Hey everyone. In this lesson
we're going to take a closer look at the Game
Mode blueprint type. So essentially the Game Mode
is what tells the engine which controller we want
each player to start with, as well as which
character we want each player to start
with in our level. So if we go to the
third-person game mode that we have in our content
browser hip and open it up. You can see that we've got
the class defaults open here, and it gives us a few different options under the classes. Now, we're just going
to be focusing on the controller and Default
Pawn class for this lesson, because those are the main
ones that you'll be changing. We will be going over the other settings
in a future lesson. But for the player
controller class, this is the player controller
blueprint that will be spawned for each player
that joins the game. Now currently it's set to BP example controller
from our last lesson. But if we wanted to, we
could click this and change this to another controller.
If we wanted to. Then we have the
Default Pawn Class. Now, currently it's
set to the BP, third-person character because
that's the default value. This is the third
person template. But if we wanted to, if
we add another character, say a vehicle, for example, that we wanted to start with. Instead, we could select
that here in the drop-down. Now, because this blueprint doesn't actually
have any code in it, It's given us this view. But if you want to get to the
main full blueprint editor, you can always just
click this option up here to open up the
main photo editor. And that gives us access to all the settings
you would expect, the components, the
Event Graph and so on. Now the game mode does
exist in the level, is a child of the actor types, so it can have components. We can also write code in it
like any other blueprint. We can also create
our own game mode. So if we go to the Content
Browser and just right-click, go to Blueprint Class. And we've got an option
for Game Mode base here, but that's a little bit more of a cut down version
of the game mode. So if we go in all classes
and search for Game Mode, you can see that there's
a Game Mode option here. I prefer to use this
one just because it comes with a bit more
functionality built-in. So we'll click Select to create a new blueprint
using the game mode. And I'm just going to call
this BP example Game Mode. If we double-click
that, we can open up. And I'm just going to drag
the tab up to the top here. Now, other than being the
blueprint where we can set our starting controller
and pawn classes, we can actually add
code to our game mode. Now, typically, you
would add code to the game mode that moves
the game along in some way. So for example, if
I'm begin play, you wanted a timer to
count down and then the game to end or
a new map to open. You would typically do that inside your game mode blueprint. Now a useful thing about
the camo blueprint is you can pretty much
access it anywhere. So an example of this
is if we were to go to our ThirdPersonCharacter hip. Now I've got some leftover code from our previous lessons, so we'll just delete this. And if we right-click and
search for it gets game mode. We can use this node to get a reference to our
current game mode. And currently it's a
game mode base output. So what we can do is we
can just drag out on cost to our example game mode. And the reason we can
do that is because our example Game Mode is
a child of the game mode. And the Game Mode is a child
of the Game Mode base. So we can use that
cost node to access our functions and variables
from our example game mode. So if I go back to my game mode here and I create
a new variable, I'm just going to
call this game name. And I'm going to set
mine to a name type. And I'll set this to say
def much for example. We can pull this. If we go back to our
ThirdPersonCharacter, we can drag out and
search, forget game name. We can access that variable. If I add in, say print string, we can just print
string that out when we press one on our keyboard. And we'll compile. Now, if we were to
hit play right now, this wouldn't work and
there's a few reasons flat. We haven't actually set our game to use our
example Game Mode yet. And also we haven't set our game mode to use our
third-person character. So if we go back to our
example game motor, and then the cost defaults, we can set our default
controller class and our default **** class. So I'm going to set
the default **** to the BP ThirdPersonCharacter. And we'll set the
controller class. We can change this to
our controller from our last lesson or just leave
it as player controller. I'm going to leave mine as
player controller for now. We'll just compile. Then we need to go to the
project settings. So if I go to edit up here on the top and we go to
Project Settings, I'll just drag this across
from my other screen. Then we need to go
to maps and modes. Now, maps and modes as well, we can set the default
game mode for our gang, and this will be
the game mode for every map that we create. So currently it's set to
third-person game mode. If I change this here, I want to select my
BP example game mode. So now when we create new level or we hit Play
and our current level, it will use the
example game mode instead of a third
person game mode. Now, from in here,
we can also set our default **** class and our default controller
if we wanted to, personally, I prefer to just
go to the blueprint itself. So go to our example Game
Mode and change it in there. But if you want to, you can change those settings
and here as well. Now there is another
place that we can set the game mode and that's
in our world settings. So if we close our
project settings and go to the third person map, I'm going to go to
Windows and I'm going to tick on world settings. Yours might already
be ticked on, but mine isn't. So I'm just
going to take that on. And then here there are settings
for this specific level. You can see that we've
got a game mode category and we can override a game mode. And this basically just says
that for only this level, we want to use a
different game mode from our default one that we just
set in our project settings. You can see that
this is actually set to our third
person game mode. So if I was to hit play, even though we've
set our example Game Mode in the
project settings, this just this level
on its own would actually still use the
third person game mode. This setting is useful
because you may want to gain mode that
allowed levels use, apart from a couple
that you might have a specific game mode that you want to use
for those levels. So you would use this
setting to take control of the Game Mode and sell
it to whatever you want for this specific level. So for now, I'm just going
to set this to none, or we can just click
it and select none. And that will clear the
game mode override. So now when we hit
play and we press one, you can see that it's
printing out death match, which is that variable that we set inside our
example game mode. But we can access it really easily just by using
the get Game Mode node casting to our game mode and then we can
access that variable. And this will show work for
events and functions as well. Now, lastly, I just
want to cover some of the built-in functions that
come with getting most. So if we go to our
example game mode, now, if you remember with functions, we can override functions
from our parent blueprints. So if we click this
override option here, you can see we've got quite
a few functions here, most of them coming from
our game mode base. Now if you remember from
our functions lesson, when you override a function, it basically tells the engine that you don't want the code that's inside this function
in the Game Mode base to run, you want to use your own code. Now as a warning, you want to be careful with overriding
these functions because pretty much overriding any of them can
break your project. So for example, if
I was to override, spawn Default, Pawn
that transform, if I click that, you
can see that we've got this function that's built
into the game mode base. And this function
is responsible for actually spawning
in the character. So if I compile this
and I hit play now, you can see that
I no longer have a character and I've no
longer controlled anything. And that's all because
I've just override it. Function that actually
spawns our character. So I'm not gonna go through
all of these functions. There are quite a few. Some of them are
self-explanatory, some are a little
bit more complex, but just be aware when you are overriding these functions. If you do choose to
do that, be careful. They can break your project quite easily because
these are like core functions for making sure that the game
actually works. Also, if you hover
over these functions, so you can see you actually get reasonably decent tool tips that tell you exactly
what each one of these functions do and
are responsible for. So that's gonna be it for
our game modes lesson. Hopefully you now
understand a bit more about what
game modes actually do in the engine and how you can use them
in your projects.
23. Basics (Utility Nodes): Hey everyone. In this lesson we're
gonna be taking a close look at
the utility nodes. Utility nodes are useful
for a few different things. They allow us to choose which
code is going to be run, how often that code is run. And they can also help us just tidy up the code of our project. So you can see from
our last lesson, I've actually
restarted just with a brand new
third-person template. So you might want to
do the same as well. And then I'm just
going to open up the ThirdPersonCharacter. And I've added a few of the more commonly used utility nodes here that we're just going to
go through in this lesson. So to start with, we'll take
a look at the sequence note. So if we move this
up here for now, now a sequence note takes in one execution input and has
multiple execution outputs. We can add new outputs by clicking the Add
pin button here. And we can remove them
just by right-clicking and selecting the remove
execution pin option. The way the sequence
node works is it takes an input like say,
a beginning play. Note. We can connect
that up here. And it will run any code
connected to the then 0 PM. Once all of that
code is executed, it will then run the
than one code and then the next code and the next code and so on until
all of the pins have run. Now, the main use for
the sequence node is to just keep your code a
little bit more organized. With blueprints. If you have a lot of code, you can tend to have these
really long lines of code. A sequence node allows you to just break that up
so you can have multiple lines and keep things a little bit
more organized. You can also use the sequence
node inside a function. So if I create a new function, I drag out when I searched
short sequence in C, I can create a sequence node. The way it works
inside a function, just something you
want to be aware of. It say I had some code up here, say I print string
and then if node, and then if I had from
hair a return node. Now remember when you
run a return node, it finishes the function. So if this return node where
to run any code that you had connected to any
of these other pins inside your function
wouldn't run. So that's just something
to be aware of when using sequences
inside a function. So now we'll go back to our event graph and we'll
take a look at the gate node. So if we delete on
those up pit, again, allows you to run code
that's connected up to the exit at a frequency of whatever inputs
to the internode. So what I mean by
that is if I connect a tick up to the internode here, then our exit code
will run every tech. And the gate allows
us to essentially open and close this exit PM. So if I add a, if I right-click
and such what input, input of them, one, we can
create an input of them, one. Connect that up to open, copy and paste this. Now select the note here, this little keyboard
icon and press two, and actually just changes
this to a 2-input now. And I connect this up and I'll just add a print string here that we're doing this all inside the first-person,
third-person character. Sorry. We'll compile and
we'll go to the map. It play. Now you can see that my
print string isn't running. And if I go back to the
third-person character here and use the debug option. You can see that the code
for my tick is running. It's going into the gate,
but the exit isn't running. Now if I go back to my
level, I press one. You can see that that print
string is now running. And if we go to our
third person again, you can see that the exit
code is now running. And that's because I pressed
one and I opened the gate. If I press two, I can
now close the gate. If I go back, you can see
that the code is no longer running and that print
string isn't running either. Now there are a
couple other options on our gate node.
We can use toggle. So this will basically
just the gates currently open and we want to
toggle, it will close it. If the gates currently
closed and we run toggle, toggle, it will open up and then we have an
option to start close. So currently it starts closed. But if I untick
this, we hit Play, you'll see that it actually
just starts running instead. Now, I've been running
the gate with a techno. So if I just exit
out of play here, we could use a timer
instead of a tech node, which is probably
better for performance. So we'll just do
a plug-and-play, will connect up a timer. So if you remember the
setTimeout by event node, we drag out from this and create a custom event which
called a timer. We can connect this up to
our gate instead of a tech, that is to say 0.5. So every 2.5th this
time will run, will take on looping. Now, when we hit play, you can see that our Hello
print string is only running every 2.5th
because that's, that timer is what is
controlling our exit output. So next we'll move
on to our next node. So we'll just exit out of
the plane editor there. And we'll use the do once note. Now, the D wants to know
pretty much does what it says. It takes in an input, runs a complete and
then if it's run again, it won't run the complete
code. So we can try this out. If I just delete my gate note, it will connect this up
to our timer that we just used and plug
this into completed. So we should see our
print string one. Hello once and then
nothing else happens. So I'll hit play and
see that that happens. And even if I go to my
ThirdPersonCharacter here, you can see my time is running, but the D once is blocking it. Now we can reset
this do once node. If I take the one pin here
and plug that in to reset, and I can pull out and hit Play. You can see hellos printed out, but it's not printing anymore. If I press one, you can see
it's printed out again, but now again it's stopped it. So I'd have to keep
pressing one to keep opening and resetting
that do want snowed. Like our gate node, it does
have a stock closed option. So if I take this
on and we hit Play, you'll see that we don't get any print string
until I press one, which resets that node. Now if we exit plan editor, we'll move on to the next node, which is the do n. And n basically does the same
thing as I'll do want snowed. But it allows us to control how many times this node will run before it
blocks the code. So if I delete this, I plug in the enter two timer here and the exit to our
print string and say, we want this code to run five times and then
we want it to stop. So we can plug the counter
into our print string here, and this will just output
how many times this is run. If we can pull, we hit Play. You can see that it's
printing out the numbers, but once it gets to five is
stopped because ARRA do, a node is blocking the exit. And we can reset
this node as well. So if I take the reset pin, plug that into one, hit play, we can reset, or sorry, count to ten or five, sorry, then we'll press one and you'll see I
can reset it again. So now we'll go back to our ThirdPersonCharacter and take a look
at the next node, which is the flip-flop node. Now this basically just when
it gets run, it we'll run a. Then if this node gets
run again, it will run B. And it will just
keep going between these two pins each
time you run it. So if I connect this up to
our one input event here, and I print string
from a, we can do, I'll just set this to a copy and paste this and set this to. We will compile and play. You can see that our timer
there is still running. But if I press one and
you see a, B, a B. So you can use this to cycle
between two parts of code. As a side note,
with the flip-flop, you probably won't
be using it when you're a little bit more
confident with coding. But it can be handy if you're creating a quick
prototype or something. But typically you
would want to use say, a branch, node and a Boolean. And that would give
you much more control over how this code would work. And then moving on lastly, we have our latent nodes. And if you remember that's
the latent because they have these little clock
symbols and the corners. Now we've used the
delay node before, allows us to essentially hold the code up for a
certain amount of time. So if we were to delete this
code out with delete this, and I'll remove this as well. So when we press one, we could have a delay and
then we could do some things. So I could say call
the jump of them. This will actually make
our character jump. I'll set the delay
to say two seconds. So now when I hit play and
I press 12 seconds later, you see that the
character jumps. Now there's a different
type of this node. So if we exit out
of play here and go back to the
ThirdPersonCharacter. We can use the re-trigger
are both delay. Now the difference
here is if I was to say just keep pressing one while my delay node is counting down
that the duration, this node would just ignore the input and it would count
two and then jump would run. Now, a re-trigger or delay will keep resetting every
time it receives an input. So if I use the word trigger delay instead of
just the delay node, her and I hit Play and
I start pressing one. You've seen my carrots
won't jump even after two seconds because I keep
resetting that timer. If I stop pressing it, it will wait two seconds now
and our character will jump. Now, there's one last note
that I wanted to show you, and that's the delay
until next tick node. So if I drag this up here, you can see that this
is also a latent node, and this essentially just
blocks of code for one frame or makes the code weight one frame before the completed
pinna then runs. So if we were to use this with the one and I'll
jump function here, you won't notice any
difference for I press one, it will seem like it's instant, but it is actually
waiting one frame before it tells the
jump function to work. Now, this does have uses
sometimes in blueprints, you might need to
wait a frame before a variable gets set or
something like that. So that node can be useful
for those kinds of things. That's all for our
utilities nodes lesson, we will be using most of these
again in future lessons, so you'll have a chance to
get familiar with them.
24. Basics (Game Instance): Hey everyone. In this lesson we're going
to be taking a look at the game instance blueprint. Now the game instance blueprint is created when our game first starts up and remains there
until we close the game. And unlike other blueprints, if we change level, our game instance
isn't destroyed. It's permanent for as long
as we're running the game. And that makes it a really
useful blueprint for storing information that you need to
transfer to other levels. For example, you may have variables that you
want to transfer from your main menu level
into your game world. Well, you can use a game
instance to do that. So to start with, we're going
to create a new blueprint. And that blueprint
is going to send our character to a
different level. So we're right-click, go to Blueprint Class,
create an actor. I'm going to call
my DP underscore teleport. Teleport. There we go. And we'll open that up. I'm just going to drag mine
up to the top bar here. Now this is gonna be
the blueprint that actually sends our player
to a different level. So we'll add a box
collision just so we know when they
enter this actor, I'm just going to move mine
up a little bit like that. Then we'll head to
the Event Graph. And we're just going to be using the actor begin overlap node. So it will delete
these two and we'll drag out from other
actor and just cost to character to make
sure that we only run this code if the overlapping
actor is a character, then we're going to use
the open level notes. So we'll drag out and
search for open level, and we're going to use
Open level by name. And this allows us to just tell the engine to open a new level. And it will open the level
that we set the name for. This I'm just going to drag
out and create variables. So we'll do promote the
variable and we'll leave it as level name and a name
variable type like that. I'm also going to take on instance editable, and
then we'll compile. Next, we need to create a new level that we're
going to teleport to. So we'll head to the
Content Browser, then to third-person maps. And in here we've got
our third person maps, so we're just going
to duplicate this. Now. I can right-click and hit
Duplicate for some reason. But what we can do is just drag this over the maps folder. You can see we can do Copy here. Now actually create us a
copy of our current map. Now we'll open up our third
person underscore to map. I'm just going to
select Save actors. Now we're in that second
map and I'm just going to delete a few things so we can tell the difference
between the two. So we just select all these things over
here, delete these. So we know that when
we enter this map, we are in our second map. Now we'll head back to
our third-person map. So we'll double-click
to open that. I'm going to select,
Save, select it. And now we're back in our
first first-person map. And we're going to add
our teleport to this map. So we'll go to blueprints
and drag one in. I'm going to make mine
a little bit bigger. We can also go to our
teleport blueprint, select the box and just
turn off hidden in game so we can actually see
the collision like that. And now we need to use that
variable that we created on our teleport to tell it which level we want
to teleport to. So we'll go to Details and you see we've got our
level name here. So what we're gonna
do is go to maps, just right-click or
third-person underscore two, we'll do Rename, then do
Control C, and click away. And then we'll paste that name
into our level name here. And then we can test this out. So I'll hit play or
run into the box. And you can see that
we've now transported to our new second-level. Now when we open a new level, everything in the previous
level is destroyed. Our character player
controller game modes is all destroyed. And then when the new
level is opened up, our character is being spawned. A new controller
and Game Mode are also created for our new level. So that means any variables
that you had set in your character before we transported over
to this new level, all of those will
be lost and we'll start again with a
fresh character. And to just give you
an example of that will exit out of plane editor, head to our blueprints than
third-person character. I'm just going to
create a new boolean. We'll call it example, and we'll use a tick node. So I'm just going to right-click
and search for tech. On tech, we're just going
to print out whether or not our example
variable is true. So we use a print string. We'll connect this up
to here, like that. And now I'm going
to add an input, so we'll call this
input event one. So when we press one, I want to set this
variable to true. So we'll do this and
then we'll compile. So now when I hit play, you can see that
we're currently in our first third-person map. If I press one, you can see that our variable becomes true. But if I run into our box
and we go to a new level, you can see that that
variable is now switch to be false because we've got a
new character blueprint. Now we can use our game
instance to actually save that variable for us and
carry over to the next level. So what we'll do is exit out. We're going to create a
new blueprint instance. We'll right-click and
we'll go to blueprints. We want Blueprint class. And in the options here, there actually is no
game instance class. So we're going to go down to all classes and
search for instance. And then we're going to select the game instance down
here and hit Select. And now that's created us a
new game instance blueprint. So we'll call this BP
underscore example, game instance like that. Then we can open that up. And you can see that this
is just a basic blueprint. It doesn't even have
any built-in variables. You can see if I
click class defaults, there's no variables here. This is just a pretty
simple blueprint that we can use to
store variables. We can create functions, macros like other
blueprints as well. There are some override
double functions in here, so you can override the init, which is basically the
function that will run when we first create
our game instance, we have a network error, which I won't be
covering in this lesson. We've got shut down and
this will run when we actually close out our game. Then we've got travel error. And this will run if
we have some sort of problem transporting
to a new level. For now we want
our game instance to actually store
a variable for us. So we're going to
create that variable. I'm just going to call
this example again. And we'll compile. Now before we open
up our new level, we actually need to
set this variable. So it will go to our
ThirdPersonCharacter here and we'll create
a new function. I'm just going to
call this update gain instance, like that. Now the cool thing about game
instances is you can pretty much access them from any blueprint the same
as the game mode. So we can just right-click
search for Game Instance. And you can see we can use the
get Game Instance and this just returns a reference
to our game instance. Now because we created our
own game instance blueprint, we need to cast that to be
able to access its variables. Or you could set up a Blueprint Interface
if you wanted to. But we're just going
to stick with casting. So I'm going to use
a cost to example, and then we want example, game instance like that. So now we will just move
these nodes down here and connect them up to the
input of our function. Then we want to use set that example variable that
we've created enough. So we'll do set example,
connect this up here. And then we'll grab our example variable from our character, and we will plug that to set. The set node will compile. So now we actually need to run this function before we
open up our new level. So we'll head to teleport and we will inherit, run that function. So we're going to need to change our costs note here to
a third person costs. So we will drag out and do cost. Third, we want the
ThirdPersonCharacter because that's the
blueprint that has our new function
will drag out and search for update game instance. And that will set
our variable inside our game instance to whatever
it is from our character. And then we'll
connect this up to our open level like that. So now when our
character spawns, we need it to actually
read the example variable we've created inside the
example game instance. So to do that, which can
go to the Event Graph, will create a begin planets. So such will begin play again, which can get the
instance or sorry, get the game instance. And that will give us
access to the blueprint, will cost to the
example Game Instance. And then we'll get
its example variable. So we'll drag out
and do get example. And we'll use that to set our characters example variable. So we'll set this like that. And we'll run this
on Begin place. So whenever our
character spawns it, read whatever the
example variable is in our game instance, and then set that to
its example variable. Now there's a couple
of more things we need to do before we
can test this out. The first thing is we
haven't actually told the engine to use our new
example Game Instance. Now we don't actually do this in the game mode like
most of the things, we actually do this in
our project settings. So we'll have to edit
then Project Settings. And we're going to search
for Game Instance. And you want the game
instance class here, and we'll change this to the
BP example game instance. Now the engine knows to
use that game instance. And then secondly,
we're gonna go back to our second map that we created. So I'm just going
to open that up and we'll hit Save here. And in here I'm
actually going to add our teleport blueprint
here as well. So I'll just drag that in, scale up to be a bit bigger. I'm adding this
just so we can move back and forth between
our two levels. We need to set a level name. So that'll be the name
of our first map, which is third-person map. I'm just going to
right-click select, Rename, copy this, and then paste that into our level variable
here like that. Then we're going to head back to our first third-person map. So we'll just open
that up and then we'll hit Select, Save, select it. And then we're ready to actually test this out. So I'll hit Play. You can see that the
value is currently false because we've just started
and I haven't set the value. But if I press one,
it becomes true. Now, if we went
into the teleport, it will remain true even once
we're in our second level. And that's because our character
is reading that variable from our example Game
Instance and then setting up. And it doesn't matter
how many times we switch between levels, it will always read that value because our game instance isn't being destroyed unlike our
character and controller. Now of course, this is a
pretty simple example, which is storing one variable
in our game instance. And then reading up
from the character, you can store as many
variables as you like in your game
instance blueprint. And you can access
those variables pretty much from any blueprints. So we used our
ThirdPersonCharacter, but if we wanted
to, we could access our game instance
in the teleport. So we could do get
game instance. We can access our game
instance in here as well. So that's it for this lesson. Hopefully you now
understand the uses of the game instance
and how you can use it in your future projects.
25. Additional Lessons (Traces): Hey everyone. In this lesson we're gonna
be taking a look at traces. Traces allow us to
take a start and end location and then check what's between those
two locations. So to get started, we'll create
some example blueprints. I'm just going to
right-click and create a new blueprint class. It's going to be an actor, just going to call
this BP trace cubed. We'll open that up. And I'm just going to drag
the tab up to the top pair. And we'll add a new component. I'm just going to
add a cube component that will compile that. And we'll go to the Event Graph. So we're going to set this
cube up so that it will do a trace to another
cube every frame. So it will start
by deleting these begin play and the actor
begin overlap nodes. Actually use the tech
node and we'll create a new variable and we'll
just call this cube. And I'm going to set its type to BP underscore trace, trace cube. And we'll compile then in the Details panel
which is going to take on instance editable like that. And we'll compile again. Then we'll drag out and
we'll get our other cube. We want to check that it is set, so we'll use an Israeli node just to make sure we
don't get any errors. And then from r is valid, we'll drag out and
we'll search for trace. Now, if we scroll up here, you can see that we've got quite a few different trace nodes. They're all under
collision here. We're going to start with
just a simple line trace by channel. So I'll create that. Now. A line trace is essentially a single pixel line that will go from the start to
the end location, checking if it hits
anything along the way. Now, there are a few other
options on this node, but we'll set up our example first and then I'll
explain those. So what we'll do is we'll
drag out from our other cube. We want to get up to location. And we're going to plug
this into the end location. And then for the start location, we're just going to use our
current cubes location. So do get actor location. So our trace will
start at this keeps location and it will travel
to the other cube location. Now when I say travel, trace happens in one frame, it's not like it
moves slowly along. It all happens in one frame
and essentially just checks, is there an object between
the start and end locations? I'm also going to turn
on the Draw Debug here. I'll set it to one frame, and this essentially
allows us to see the trace in our game, usually traces are invisible, but this option allows us to see a trace while we're
playing in the game. One frame will mean
that the trace will only be visible for one frame. Duration means that
the trace will be visible for however long
the drawer time is set to, so it's five seconds by default. And then persistent means that the trace will be
visible forever. So because we're drawing
our trace every frame, we can just set
this for one frame. So now we will just compile this blueprint and
go to our level. I'm just going to
drag it in a cube. And we'll drag in a second cube. And I'm going to, with
my second cube selected, I'm just going to use
the other Cube option down here in the details. And we'll select R of a cube. And I'm just going to
move them both up so we can see them a little bit
better when we hit play. So when I hit play,
you can see that we've got this single pixel line that's going from this cube over to the cube
that we selected. If I press F1 to go
into wireframe mode, you can see that
the trace begins at the center of our
key pair and is read. And then once it
hits the other cube, we get this red square and
then the line goes green. And that essentially means
that up until that red square, the trace hasn't hit anything. Then the red square indicates
that it's hit something, and then the light turns
green because it's, the tracers hit something
past that point. Now, you may be
wondering why are traced and hit the cube
that it came from. And if we exit out of plane editor mode and go
back to our trace cube, you can see that there's
actually an option here called ignore self
on the line trace. And that means the trace
will essentially just ignore the actor
that did the trace. So because we're in our cube, if I untick this and
compile and then hit Play, you can see that the
line is already green. And if we hit F1, you can see our trace is
actually hitting our cube as soon as it starts and then the rest
of the line goes green. See it doesn't actually
hit our second cube. Now, that's because this
is a single line trace. It will hit one object and then it doesn't care about
the rest after that. Now going back to
our trace keep, there's a few other
options so we can set actors to ignore. This allows us to
essentially just set actors that we want our line traced to
completely ignore. So if I was to drag out
and do a make array, this allows us to just
add individual actors to an array and then add
that to our line trace. So if I was to plug
my other Cuban here and plug that
into the array, I'm going to tick back on ignore self because
we want our trace to ignore the cube that does the trace will compile
when I hit play, you can see if I press F1
or trace isn't hitting anything anymore because we've told it we don't
want it or sorry, we want it to ignore
our second cube. Now, heading back to our
trace cube blueprint, there's another option
here called trace channel. Now trace channels
are kind of like layers that we can
use our traces on. Now, the reason we have this is you may have an
object that you want to block one type of
trace but not another. So right now you
can see that we've got it set to visibility. This is a trace channel
that's built into the engine. If I go over to my cube here in the level
and I select it, I'm going to select
the cube component. I'll just make this a little bit larger so we can see
what I'm going to scroll down to the
collision category. Under Collision Presets,
you can see it's currently set to
block all dynamic. We click the drop-down here. You can see we've
got these options here that they're grayed out. That's because we've
got a preset selected. So if we click the drop
down here and click Custom, that will allow us to
customize the settings. So you can see that
for trace responses, we have visibility
and we have camera. Now, if I set our key pair to ignore the visibility
trace channel, and I go back to my cube. I'm just going to disconnect the other cube here
from our make array. So now I'll trace, will hit the other cube. I'm going to hit
Compile and hit Play. You can see if I press F1, the trace still isn't
hitting the cube, therefore has to go back
with our cube selected here. Select our cube and set it to block the visibility
again, and then hit Play. You see that it is now
hitting that cube. And that's because we're
telling this cube mesh to either ignore or block
this type of trace. Now it traces are used for all sorts of things
in game development. They used for interaction to determine what the
character is looking at. You can use them for things like footprints systems to detect what type of ground the
characters standing on. You can use them for weapons. So hit Scan weapons,
you use traces. So any game where there's
no bullet travel time that typically using traces for
the bullet calculations. So traces have a
really wide variety of uses in game development. But the important
thing about traces, we can actually get information about the object that it hit. So if I exit out of
our plan editor here, we go back to our trace cube. You can see that we've
got some outputs. Now if I drag out from my
outfit here, we can break it. And that's because it's
actually just a struct. You can see hips results
structure. So we can break that. And that gives us this
node here with all of the information about what
object, the trace head. Now we've also got
returned value here, and this basically
just says whether or not the trace actually
hits something. So typically you'd
probably want to do and if node here and get information about
the object only if the trace actually
hit something. Now I'm gonna go through
some of these variables. I won't cover all of them
because there's quite a few, but I'll go through
the more commonly used ones at the top. Here we've got blocking here. This basically does the same
thing as a return value. It says whether or
not the line trace hit something, and
that's a Boolean. Then moving down,
we have distance. Now, this is how far from the star the line
trace hits something. So if the distance between, say, start and end was
500 centimeters and the trace hit something at 100 centimeters from the start, then this distance
value would be a 100. Next we've got the
location and impact point. Now, for a line trace, these will actually just
be exactly the same value, but they will be
different for some of our other trace nodes that
we will look at in a moment. Next, we've got one of
the more important pins, which is our Hit Actor. Now this gives us a reference to whichever actor or
line trace hits. And it's very useful for things like if you're creating a gun, that Pfizer line trace or
an interaction system, you wanna know which actor
the line trace actually hit and using the Hit Actor pin here is how you would do that. We also have access
to the hip component. So that'll be the component
inside the actor that we hit. So for example, our cube, we would be hitting
the cube component. So this hit component
would be a reference to the cube inside our cube actor. These pins work like we've used actor pins and
component pens before. We could drag out from this, we could use a cost to
determine if it's say, Cast to ThirdPersonCharacter. And if the trace hit a
third-person character, we'd be able to access
that information using our costs nodes. We can use our interface
nodes as well, and we can get information
from the actor. So we could do something
like getLocation. And we can use this act of pin, like we have done
with previous act dependent types before. We also have access to the
bone name that the trace hits. So if I trace hits
a skeletal mesh, so that's an animated mask
mesh that has a skeleton. This will return the
actual bone name of the collision part
that the trace hits. So you can use these
to access bone names. And then down here we've got
our trace, start and trace. And these would
just be the same as our inputs up here
for start and end. Now, so far we've
only been looking at the line trace by channel. Now there is another
line trace node. So if we search for lying trace, you can see that we've
also got a line trace by profile and align trace
for objects as well. So if I create a line
trace for objects, this is essentially
the same node. It does the same thing
we have are out here. We have the start and end. We have the same settings, but instead of a trace channel, we have this array input
that's an object type. If I drag out from
here and use them make array that
allows us to actually set what values are going
to be in this input array. So you can see that
by default has got a world static here. I
click the drop-down. You can see that it's giving
us some object types. Now, if we go back to our cube with our
cube selected here, and go to the cube component. This refers to the
object type listed here. So you can see that this is
set to world to dynamic, which means this cube
or only be held by traces that have an
input of world dynamic. This line trace here
with world static would actually completely
ignore that cube. So that's what the input
object types are referring to. It's this object type within
our Collision Presets. We could quickly
hook this up to see if I just plug this
into my as valid, I'm going to delete our
previous line trace node. We'll plug this into our
star and listen to our end. And we will connect this up. We can leave that for now. We just set the
Draw Debug Type two for one frame will compile
and then we'll hit Play. You can see that if I press F1, that trace is completely
ignoring the cube. But if we go back to the trace, the trace cube and we change
this to world dynamic. Hit Compile, hit Play. You can see that now that trace
is hitting a cube because it's hitting that Q because
it's the same object type. And the cool thing
with this is we can actually set multiple types. So we can just add
a new pen and we could add wild static as well. We could add another input. We could set this to
****, for example. We could add as many as we
want this trace to hip. Now the last line trace
note that we will look at is the line trace by profiles. So if I search for
line trace by profile, now the inputs are the same
as our previous nodes, but we've got this profile name. Now that's referring
to the object responses that the object
we're trying to hit has. So we go back to our map
here, select our cube, and in the collision
settings you can see we've got object responses. Now, I'll use ****
as an example. So you can see ****
is set to block. So if I go back to my tracer, I'm going to set profile name to connect this up like
we have done before. Connect start to get
active location and end up to our other
cubes, actor location. We'll turn on the Draw Debug
Type two for one frame. We'll hit Compile. And when we hit play,
you can see that our line trace is hitting
that of a cube over there. But if we accept and I
select the cube and select our cube component and we set our **** object responsive
to ignore. Then I hit play. You can see that our trace
is no longer hitting the cube because our trace is done in that profiles
object response. And our cube, it's no longer
blocking that trace anymore. Next we're going to take
a look at multi traces. Now if you remember, when our trace currently
hits something, it no longer cares about
anything else along its path, it goes green and it doesn't
hit any other objects. But with multi trace
as it allows us to hit multiple objects in one trace. So if we head back to our
trace cube it now I'm going to delete this trace note that we've been using
and I'll make rent. If I search for a line trace, you can see that we've got multiline trace versions of the nodes that we've looked at. So we can do a multi-line
trace by channel. And you can see all of
the inputs are the same, but instead of a
single out here, we have an array of outputs. And this works like
a usual array. We can say get the getter
result at a certain index. So we could use the get node input an index that
we want to access from the array and
output are hit results. So if we drag out from our
get node, then we do a break. You can see that we have the same break note
we had before. And now we're accessing the first hit result from
our array of outfits. Now we can also loop through
these results as well. So we can use a loop node a for each loop note,
and if you remember, that will cycle through all of the results or all of the
entries in our array. And it will give
us access to each one of them using
our array elements. So again, we can use a
brake kit result node, access all of that
information about each one of the objects that
our line traces hit. Now other than having multiple outputs for
our hip results, the multiline trace works in exactly the same way as a normal line trace
by channel node, we provide a start
location and end location. We can say a channel that
we want to do the trace on. So currently it's set
to some visibility. We can set whether or not
we can see the trace. I'm just going to set
mine for, for one frame. So now if we compile
and we hit Play, you can see that our
trace is working. But the cool thing about multiline traces is that
we can have multiple hits. Now to do that, I'm going to drag in a new cube over here. I'm going to set my first cube to trace to that one instead. Now if I hit play, you
can see that we're still enter wireframe with F1. You can see I'm still only
hitting one of our cubes. If I go back to our code and I can actually
drag out from outfits, I'll do length will delete this trace, the
loop node for now. This will actually tell us
how many results are in our hit result array. So if we compile and hit Play, you see that it's only hitting one object even though
it's tracing to this cube. Now the reason for
that is this cube is still blocking the
visibility trace, which means that the trace can't travel through and
hit other objects. To allow that, we have to set our cube to actually overlap. The trace. So we go to visibility here
with our cube selected, and I'm going to
set it to overlap. Now when we hit play, you can see that we're
hitting two objects. If we enter our wireframe, you can see that we're hitting this first cube and then
we're seeing our second cube. So that's just something
to keep in mind if you do work with
multi-line traces. And the future is if you
want the trace to be able to travel through an object and
still hit other objects. The object needs to be set
to overlap instead of block. If it's set to block,
then any objects at the trace hits after
that object won't be outputted in our results from our multi-line trace node. Now, there are other
types of trace nodes. So far we've only
used the line trace. If we right-click and
search for trace, we scroll up here. You can see that we've got
a box trace by channel, multicast, trace by channel. We've got the sphere
trace by channel. And essentially these will do the same thing as our channel. Line trace by channel, line trace by profile and line
traced by objects, nodes. But instead of just
a single pixel line actually gives us a shape. So if we were to select,
say, for example, the square trace by channel, you can see that we've got
the same sort of inputs. The only difference
is we have a radius. This is the size of the sphere
that are traceable bit. So if I delete our
multi-line tracer, we can act up our
sphere trace channel. I'll just connect this up
to end, start and end. And we'll set the
radius to say ten. That's the size of
the sphere that will be going from start
to end location. So we'll set the draw D bucket two for one frame will compile
and then we'll hit Play. You can see that now
instead of a single line, it's this sphere shaped trace. Now this just allows you
to trace a bigger area. So say you didn't
want a bullet to be one pixel in size
when a gun fires it, maybe you wanted it to
be a sphere that was 55 centimeters in diameter, then you could do that instead. Now, like our line trace, there is a multi-version
of this node. So if I right-click and I
search for sphere trace, you can see that we've got
multi-scalar trace by channel, Maltese, fair trace
by profile and multi sphere trace for objects. So we could create a multi
sphere version of this node. You can see that it's
exactly the same, but we have our radius input and we can output
multiple hip results. Now I'm not gonna go through
every single trace node because most of
them are the same. They're just different versions
for the multi trace and then the different trace by types and then the
different shapes. But if you want to find
them, you can always search for trace and search for say, box that will give you
access to all of the box. Trace these top ones here with a single traces and then
you've got the multi traces. You can search for
sphere as well. This gives you access to
all of the sphere traces. You can search for
line, trace, line. This will give you access
to other line traces. And then lastly you've
got the capsule. These will give you
access to all of the capsule trace types. Now, lastly, I said I would tell you the
difference between the impacts point and the
location on our break now, so if we click the down
arrow here and open that up. Now on a line trace both the location and impact point will be
exactly the same, but with a sphere, for example, the impact point and the
location at different, the impact point will
be the exact point that the sphere hits the
surface of the cube. So if you imagine
right on the edge of the sphere where the red boxes, that's the impact point. The very point that the
sphere overlaps the box. Whereas the location pin here is the location
of that sphere. So our sphere, the center of it, is actually further away from
the surface of the cube. So that's the difference
between the impact point. That's the exact point
that the sphere overlaps, the cube and the
location is the center of the cube when that
overlap happens. Now that's it for our traces
less than at the moment, we will be coming
back to using traces again in some of our
future lessons though.
26. Additional Lessons (Data Tables): Hey everyone. In this
lesson we're gonna be taking a look at data tables. We use data tables to store information that we don't need
to change during gameplay, but we can retrieve that
information using blueprints. An example of when you might
use a data table is for say, if you are creating an RPG or survival game where you had hundreds or maybe
even thousands of different types of
item and you're getting each one of
those items are going to have some kind
of information that doesn't actually change
during gameplay, like for example, its name, item, description, and weight. Those values might not
change during gameplay. So a data table would
be a good way to store that information
and then easily be able to retrieve it in the
code. So let's get started. We need to create
a new structure. And that's because data
tables use structure to determine which
information they can stop. So we'll right-click and
we'll go to the blueprints, pop out and go to structure. I'm going to name mine
S underscore and that's structure of example, struct. We'll open this up.
And if you remember, we have a previous
lesson on structures. So if you haven't seen that, I'd recommend checking that out. But we're just going
to add a couple of new variables and we
will give them names. So our first one article name. And we'll set this to
a text variable type. We'll call the second one, wait. And we'll set this to a float. We'll call the next one damage. And we'll set this to an integer and will cause the
last one health. And we'll set this to
an integer as well. And then we'll save this struct. Now we're ready to
create our data table. So we'll go back to
the content browser, right-click and select the
miscellaneous category. And then here we want
to select Data Table. Now, here is where
we select which struct we want our
data table to use. So I'm going to click the
drop-down and search for S underscore example struct. I'll select that and hit Okay. Now we'll name our data table. So I'll call mine
example data table. And we'll double-click
that to open it. And I'm just going to drag
mine up to the top pip. So now we have a new
UI Layout up here. We've got our data table. Now this is the
current information that these tables storing. As you can see, it's
currently empty. And then down here we
have the row editor. So when we do have information in our data table,
we can select a row, and this row editor
will allow us to change the information that's stored in that particular row. So to create a new row or go up to the Add button
and press that. Now you can see we've got a
new row in the data table. And with that selected, I can change any of the
variables that we created inside our struct
for this particular row. Now we also have the row name. Now this is the name we'll use to access the information stored in this specific row when
we're coding and blueprints. So you always want to make
sure that you're giving your row names and your base
tables user-friendly names. So we could rename
this to say acts. For example, say we were
creating a data table for items that are going
to be in our RPG game. So you would have entries in the states table or new
rows for every item. In here, you would set the
item's name, for example, so we can set our name to act. Like I said, the weight ten, the damage to 20 for example. And now we've set this data
in this specific rope. And if we wanted to, we
could create another row. So we could click Add. And now we've got a new row. Maybe we wanted to store
information about sorts so we could create a sword row in C. I've renamed
the row name to sort, and I'll set the name to sort. Who set the weight
to save five and our damage to ten, for example. Now there are a few other
buttons up here that allow us to control our rows. So we have copy and paste. This allows you to copy the dataset in one row and
paste it onto another. So if I select my
AKS for example, and I do copy, and I select my sword wrote and I do Paste. You can see that it's
now replaced the data in my sword row with the information that
was set in my AKS row, you can see that the row
name hasn't been changed, that still is set sword. That's because your row
names need to be unique. So we couldn't create a new row, for example, and call it acts. You can see that it gives
us an error because each row needs to
have a unique name. Now we can also delete rows. So with my new row
selected here, I can hit remove
to remove the row. And we can also duplicate rows. So we can select row, hit duplicate and it
will duplicate that row. You can see that it's giving it a new name called
sword underscore 0. If now I'm just
going to remove that sword underscore 0 and I'm going to set my information back to what it was for
our SolidWorks. So I'll select Sort and
I'll set this to sword. And we'll set this to, I think it was white
F5 and damaged him. Now I'll show you how we can actually access this
information that we're setting in our data
table inside a blueprint. So we'll start by going to our ThirdPersonCharacter
Blueprint. I'm just going to open that up. And if we right-click, we can search for
Get Data Table row. You can see that we've
got two options here. I'm going to select the get
data table row node here and see we get this new node
that we haven't used before. If we select our data table, this is how we set
which data table we want to access
information from. So we only have the example
data table that I created. So we're going to select that. You can see that our
role name has actually changed automatically into
a little drop-down option. And we can see we've
got both our acts and sword rows that we created
inside our example DataTable. Now, these are just
variable inputs. So say I had a row name variable that I
wanted to plug into here. I could, if I drag
out from here, we can do promotes variable. And if you remember
that just creates a new variable of the type
that we've dragged out from. So I will just create
a new variable and see that it's using a
name variable type. It's just named it
for us row name, but this is just a
standard name variable that we can plug into our data table to tell us which row we want to get
from our data table. But for now I'm just going
to delete that and we'll use the selection menu here. So I'm just going
to select sword. Now, we've got two outputs. We've got row found
and rho naught found. Now, this is used more for if you're using a variable
that plugs into row name. Because if we use one
of these selections, it's giving us the rows that
exist on our data table. So it's always going
to find these rows. But if we had our
row name variable connected up and say
this was set to, if we can pull to show
the default value, say this was set to
something like back pack. Now, there isn't a backpack row inside our example data table. So it's, this node would run rho naught found because
it won't find that row. Whereas if it was set to
something like acts for example, then rho found would be fat, would be run because it's found that row inside our data table. Now we have an output
here called outgrowth. And if we drag out, we
can do a break node. And you can see
it's actually break node for the struct that we used or we created and we're
using inside our data table. So we can break that struct. You can see that now
we can access all of the information that we
set inside our data table. So if I was to
create a begin play, for example, we plug this
into our data table row. Like that, will make sure that
the row name is set to ax, which is then we'll
just do from row found. We'll drag out and
do a print string. And we can connect, say, the name up to our print string. And we'll compile it
and we'll hit play. And you'll see that
ax is printing out. If we go back to our
ThirdPersonCharacter and we change our row name to something
like, I think it was sold. We can pile. And when we hit Play,
you'll see that the data table inside the ThirdPersonCharacter
is finding that sword row and it's returning the information that
we store inside that row. If we wanted to, we
could change that data. So if I go to example
data table and I change the name
inside our sword row, something else, say apple. If we save this and hit Play, you'll see that it
now prints out apple, even though we're
selecting the sword row, and that's just the row name. We're using, the information
that we've stored inside that row, and
that's now Apple. Now there is another
way that we can tell our get dates, table row, node, which row we want to get
this a little bit more user-friendly than using
just a name variable. So if we remove our name variable from the
event graph here, we create a new variable. I'm going to call
this row select. Selector will set the type to data table row handler
handle, sorry. We'll create that, will
compile and will get an error from this node just because we haven't set a row in. So I'll just set this to sort. And if we compile again, you can see that the error goes away. Now we can our row select
a variable like this. Now, this is basically
just a structure that's built into the engine. So if we drag out, you
can see that we have a break data table row handle
node that allows us to access the two variables
that are set inside the row selective struct
and in class default. So if our row selector
variables selected, you can see we can say
data table and a row name. Now currently if I select
Rename and I think comes up because we haven't
set a data table. So I'll set this to our
example data table here. Now, when I select the row name, you can see that it
gives us access to both the rows exist inside
our example data table. I could set this to say ax. Now, using the row name
on our break node, we can just plug this straight into our Get Data Table row. Note, now we've gotten much more user-friendly
way of telling this node which item we want to get information about
from our data table. So if I compile, and now we would expect
our print string to print the name because that's the way we're telling
it to access. If we go back, we can
change this to the sword. And now we'll see it print out the Apple name that
we changed it to. Now, just as a side note, if we exit out of planets, you can plug this variable into the get data table
row, node as well. But I don't recommend
doing that because if you are plugging this in and you change the data table
to a data table that used a different structure
than what we're using here, you could cause errors and
problems in your projects. So typically I'd recommend just leaving this unconnected or disconnected and then leave manually setting the data
table that you're using here. Now there are other
data table note, so if we right-click and
search for data table, and we'll search for
row in C, that's a. Does data table row exist? Now, this essentially does the same thing as our
Get Data Table row, but it doesn't give us the information stored in that row. All it does is check does the row name exist
inside the DataTable. So again, we could copy
and paste these nodes. I plug in my row name him, and I'll set the data table
to example data table. Now and begin play with it. We'll just print true or false. If the data table that
we selected does exist. Now, because we're using
our row select a variable. We can only select
data tables that exist inside this data table anyway. So it's always going to
return true when we use this node to control which
row we want to select. But maybe we were using
a name variable instead. And that way we could set
a name here, say backpack. And this row doesn't
exist our data table. So when we hit Play, you'll
see that it prints false. If I go back and I change
this to say acts that, and we can hit Play. You'll see that it's returning
true because that row does exist inside our
example DataTable. Another node is the, if we delete this code
here just to make it a little bit more space,
I'll move this up here. If we right-click and
search for data table, you can see that we've got
to get data table row names. If I create this node, you see we set a data table. We'll set the
example data table, and then its output is
actually an array of names. And this will output an
array that contains all of the names of the rows that exist inside our
example data table. So if I connect this
up to begin play, we'll loop through
these results. So this node will run for every row that exists
inside our array. We can just do a print
string like that. Now, this will print
out all of the names of the rows when the game starts. So if we hit Play, you can
see that it's printing out wax and it's
printing out sword. Now. Lastly, I just want to explain how composite data tables work. Composite data tables
allow us to take multiple data tables
and combine them so we can access multiple data tables when we select one
specific dates table. So what I mean by that is if we create another data table, now, these data tables have to use the same structure voice. We won't be able to
combine them together. So we'll create a
new data table. We will use again the S
underscore example struct. And I'll hit Okay, I'm
going to name this. We call this weapon items. So for example, you could have different data
tables for weapons, consumables, medicine, things
like that if you wanted to, if you were making items
for say, an RPG game. So open up weapon IPython items. And I'm just going to
create a couple of new rows of cool this shot gun. And I'll call this one rifle. Set the name to rifle. Rifle as well. And also the shotgun
to shot gun. Now set the weight to say for, for the shotgun and six for the rifle
damage will set to 30, and chocolate more
set damage to ten. So now we have these rows inside our weapons
items data table. Now, if we go back to our ThirdPersonCharacter and we go back to the code
we created before. Now, those rows are inside
a different data table. So if we select our
row selector here, you see I can't select
those rows because currently we're using
the example data table. And if we were to plug in, say, a row name, and we were to plug this in
and we were to manually set the row name to say shot gun. When this code runs, it would actually not find
this rope because again, that row exists in
our weapon items, not inside our
example data table. So there would not be found. Now because the example
data table and the weapons item data table
use the same struct. We can combine them together
using a concert data table. So we'll go to the content
browser, right-click, go to miscellaneous, and we want to create a
composite data table. Again, we have to
pick a structure. Now, this needs to be the same
structure we use for both, for example, data table and
weapons items data table. So select the example
struct hit, Okay? And we'll call this the master
item list, for example. We'll open that up and
we've got a new editor. There isn't actually
much you can do inside a composite data table. We can create new rows
or anything like that. What we can do though
is add parent tables. So we'll add a new element. And we're going to set this to our weapons items shouldn't see. After doing that, we can now see our weapons items inside
our composite data table. And we're going to
add another element. And we're going to set this
to our example data table. You can see when I do that, those items that are inside
our example data table also added inside our
master item list. Now, we can't edit
these in here, or we can basically do is
add new data tables and combine the rows together in
one composite data table. So now that we've got all of these items inside our
composite data table, if we go back to our
third-person character, instead of using the
example data table here, I'm just going to disconnect
the row name for the moment. We can set this to
the master item list. That's our composite data table. And now if you go
to the row name, we can actually
select our shotgun, rifle and these
arrows that exist in the weapons item data table. Or we can select the acts and sword rows and those exist
in our example data table. This allows us to combine
multiple data tables, as long as they're using
the same structure into one big data table that we can then access
inside our blueprint. That's helpful for organizing. If you have a lot of data
that you're going to be storing inside
of data tables. And if we go to say our weapon item status
table and I add new rows, I'll call this a
knife like that. And we save. If we go back to the ThirdPersonCharacter
Blueprint, we can click the drop-down
here and you can see that knife is now showing up and it will update
automatically if we add or edit the information and
Eve are our weapon items, dates table or the
example data table. Lastly, if we go to
our row selector here, we can also use the composite
data table here as well. So if I go to the
Data Table option, we can set this to
master item list. And now if we compile and
we look our row name, you can see that we can access
all of the weapons from both our example data table and whole weapon items
data table here as well. Then we can just plug
the right name in. And now we can easily use
our row selector to select any of those rows from
either of our data tables. Again, don't worry
about this error. It's because we didn't
have a row name set. If I compile, you can see
that the error goes away. So just to summarize, data tables are really
good at storing lots of information that doesn't need to be changed during gameplay. If you have information that
does need to be changed, then you can't store that inside a data table because you cannot change dates table
information during gameplay.
27. Additional Lessons (Overlap Nodes): Hey everyone. In this
lesson we're gonna be talking about
the overlap nodes. Overlap notes are a really
good alternative to using Box or sphere
collision components. Now a really common thing I see with beginners is
you tend to open up their levels and
they're filled with Box and sphere
collision components. Now, these can work and they're reasonably
easy to work with. But the problem is later on
in your project when you have maybe projectiles or traces or vehicles trying
to move around, these collision boxes
and spheres can interfere with those
systems working correctly, might require you going round and changing
collision settings in hundreds of different box and sphere collision components. So overlap nodes gives us a useful alternative to using
Box and sphere components. Sometimes we can go to our ThirdPersonCharacter and I'm going to set up an example. Let's right-click and
search for input. One. This is a note that
as we've used before, will run when we press
one on our keyboard. And if we right-click, we
can search for overlap. You see that we've got
different overlap notes here. I'm going to start with the
box overlap for actors. So we'll create that function. Now we have some
inputs for this node. We've got box position. This is the location that the
box check will be done out. We've got box extent, which
is how large the boxes. We've got object types. So these are the
types of objects that are box overlap
will detect. If you remember from
our line trace lesson, we search for make array. We can set which types of
objects this node will detect. We can add multiple
inputs to this as well. So we wanted to detect, whoa, static, world dynamic. If you remember when
we go to an object, say in a world like
this ramp over here, if we select the mesh component, will scroll to the
collision settings and you see currently
it's set to default, but I'm going to
sell it to custom. And if you check
the object type, you can see this is currently
set to wild static. So our box overlapped would detect this
object because we're telling it that
we want to detect world static object types. Next we have our
actor class filter. This tells the box
overlap that we only want to find one type of actor so fast to set this to say
third-person character like that. Our books overlap node would now only return
ThirdPersonCharacter Blueprint. Don't forget to clear this, otherwise our example
later on won't work. So make sure you
set this to none. Then lastly, we have
actors to ignore. Now this is just an array of
actors that we can input, tell our books overlap that
we want to ignore them. So we could drag out from
this and do a make array. We could drag out from that make rate and
search for self. And now we're telling
the box overlap that we want it to ignore our ThirdPersonCharacter
and the outputs of this node or out actors. This is an array of actors that the box overlap, overlaps. And then we have a return value. And this is just a Boolean that'll be either true or false if the box overlap node
overlapped anything. So now let's set up an example. We'll get the actor location, and this is where we will
do our box overlap checks. So we'll connect this up
to box position will set the box extent to say
200 by 200 by 200. We'll set the object types. We'll leave this as
static and dynamic. Make sure that actor class
filter is set to none. Otherwise it won't be able
to detect any other actors. And we're going to
leave this self plugged into the access
to ignore here as well. We could just plug this
into our notes here. But something I like to use
when I'm using Box overlap actors nodes is a debug node. So if we right-click
and search for debug, sorry, draw debug box. This node allows us to create a visual box in the world that
we can use for debugging. So I'm going to plug this
into our Draw Debug box. And I'll plug this
into boxes overlap. And for its center, we'll just use the actor
location and we're going to set it to the same extent
as our box overlap. Sauces to two hundred, two hundred, two hundred. I'm going to set the duration to three seconds and
thickness to one. By doing this, we're
just going to create a visual box and the level for three seconds at
the same location and size as our box overlaps. So we can get an
idea of the size of the area that we're checking
for overlapping actors. Now, I'm just going
to drag out from our actors raping and I'm
going to search for length. And we'll just use
this to detect how many actors were
actually overlapping. When we run our books
overlap actors node. So I'll plug this into a print string like
this, and we'll compile. Now we can test this out. So if I hit play
and I press one, you can see we've got this
big box and you can see that our text is
printing out one. And that's because currently
our books overlap. Actors note is
only for lactating one actor. That's the floor. And the reason for
that is we're telling it to ignore our character. If I run over here
and press one, you can see that it's
gone up to three because we're hitting the ramp, this square and the floor. This is just an easy way to
detect what actors overlap a certain area without
having to create a new box or sphere
collision component. Now there are other
versions of this node. If we hit escape and go
back to our third carrot, ThirdPersonCharacter
Blueprint and we right-click and search for overlap. You can see that we have a
box overlapped components. Now, this works the same
as our box overlap actors. It just searches for
components instead. So instead of
returning the actors, it will return the
components that it overlaps. So for example, if our
floor was overlapping, our box overlapped
components check. It would return instead of
the cube act to reference, it will return the stack
Mesh Component restaurants instead out of the out
components are raping. Other than that, everything
is the same with this node. You can set the position size, object types and so on. Now we also have different shapes for these overlap nodes. So we can create, say,
a sphere overlap. You can see that we've got
our sphere overlap actors and sphere overlap
components nodes. And lastly there is also the capsule overlap
nodes as well. So you can see we've got
capsule overlap actors and capture overlap components. And these are just
different shapes that we would check for overlapping
acceptors or components. So that's it for this lesson. It's a short one that
I just wanted to do on these nodes because I
find them really useful. And hopefully they can
cut down on the number of box and sphere components
that you have in your levels.
28. Additional Lessons (Inputs): Hey everyone, In this
lesson I'm going to be talking you through
the input system. Now, in Unreal Engine five, we have two inputs systems. We have the original one
from Unreal Engine four, and we've got the new
enhanced input system that's now in
Unreal Engine five. In this session, I'm
gonna be talking you through the original
input system. And the reason I'm doing
that is a lot of projects, at least at the time
of filming this, still using that
original system. Then in our next lesson, I'll be talking you through the new enhanced input system. Now what do I mean
by input system? And input system is
how we take player pressing a button
on my keyboard or their mouse or a gamepad, actually translate that into code being run in
our blueprints. Now, we've already used some input nodes in
our previous lessons. If we head over to the ThirdPersonCharacter and I right-click and I
search for input. One for example,
you can see that we've been using the
one input event, and that's the
event that will run if we press the one
key on our keyboard. If we head over to
the Details panel, we can actually change this one input to work for we like, we can press this button here and then select the
key we want it to use. So I could press L, for example. Now this node will run
whenever, always pressed. Or we can click this drop down here and we can
look through all of the different key inputs that
the engine has built-in. Now, these kinds of nodes are really helpful for
testing things, debugging, just getting an input into a blueprint quickly. But they're not
particularly useful for full games or
finished games. The reason for that is
most modern games have a key binds menu
where the player can rebind keys to four
different actions. Now, if you're using these
nodes and a finished game, you won't be able to do that. And that's where an
input system comes in. Now, in this lesson, I'm going to be
talking to you about the input system
from you before. And the reason for
that is a lot of projects that you may open up. We'll still be using the
input system from UE for. So it's a good idea to just get to grips with how it works. Then in our next lesson, we'll be taking a look at the
new enhanced input system that's comes with
Unreal Engine five. So to get started,
we'll look at one of the key inputs that comes
with third-person character. If we scroll down here and
find the jump input action, you can see that instead
of saying a key name, it says input action jump. Now that's because
this input action is actually defined
in our input system. And then in the input
system we assign keys. So to find this system, we can go to Edit
Project Settings. And then here we go down to
the inputs section here, and that's under the
engine category. In here you can see we've got action mappings and
access mappings. Now, mine's already opened up, but yours might look
a bit like this. We click the arrow next
to action mappings. You can see that we've got
the jump input action. And then under that, if you
click the arrow next to it, you can see that the
default key bind for it is the spacebar. And we also have a key buy-in for the gamepad here as well. So essentially what this
is telling the engine is we want to create
an action mapping. Now an action mapping
is similar to our input events that
we've used before. It can either be
pressed or released. And we're telling
it we're creating a new action mapping
called Jump. And we want these two keys
to be bound to that action. And that's why when we play
in the third person map, if I press Space, this
jump input action will run pressed. And then when I release space, released will run
and it will run the jump and stop
jumping events. Now we can also create our
own input actions in here. So if you go back to
the project settings, we can just click this
little plus button here to create a
new input action. I can call it
something like shoot, for example, will
set the key to. So you can set the key in multiple ways and click
this button here, and then click the
key that you want. So I can just left
mouse button and you'll see it's automatically
picked up for me. Or you can look through all of the different key
binds just by clicking this down arrow here and
going through the options. Now we've created
a new action input and its name is shoot. And when we press
left mouse button, that shoe event will run. If we go back to our
ThirdPersonCharacter, we'll right-click and
we'll search for input. Action shoot in C that under impactions we have
are now shoot event. And this will run whenever we press our left mouse button. So I can add a
print string here. And I'll just put pressed. I'll copy and paste
that and put like that. So now when we hit play, you can see that when
I press mouse button, it's registering
pressed, and when I release, it's
registering released. Now the good thing about
this system is you can add multiple keys to be
bound to the same event. So say your game was worked on desktop and it worked on
console and VR as well. You can have inputs
for the VR, jump key, the game pad ki, and that could all be underneath the shoot category if we
want to add new inputs. So we can just click
the little plus in C, I can now add a new key. I could say press K for example. Now k will also run that shoe event as well
as left mouse button. If you want to
remove any of these, we can just click the
little trash can icon here. If you want to remove a
whole action mapping, you can just click
the trash can next to the name of the action
mapping like that. Now keep in mind if
you do that and you still have the event and
the thing if we can poll, you'll see we'll get a warning. And that's just telling us that. Mapping no longer exists
in our project settings. So we'll delete this for
now because we're no longer using it and we'll compile
to get rid of that wanting. Next we have access mappings. So if we go back to
Project Settings, you can see that we've
got access mappings. I click the little
drop down here. You can see that
we've got options for mood forwards and backwards. Move right and left. And then we've got
the same options for gamepad and gamepad
look up and down, as well as mouse look up and
down at the bottom here. Now access mappings
work a bit differently. They run every frame. So what I mean by
that is if I go to the move forward and backwards it and I
just add a print string. So we just add a
print string here. You'll see when I hit play, it's printing out every frame. I'm not pressing any buttons, I'm not doing anything at all. That access mapping will be
running every single frame. And that's the same for all
of the access mappings. So that'll be the same for
our move right and left, and also for our gamepad, look up and down as well as
our mouse look up and down. Access mappings also
provide an access value. Now this is essentially how much or how much of the input
is being received. So if I take my axis value here, and I were actually, we'll delete the
print string here, and we'll connect a new
print string up to our turn, right and left for
mouse, the sim. And I'll plug the x value into my print string
and I'll compile. So now you can see I'm
not moving my mouse, so the axis value is 0. But if I start moving
my mouse slow, you can see that the
access amount increases. Now, that's
essentially what tells the engine how much
I'm moving my mouse, how fast I'm moving it, and then it adds that value
to arc, camera's rotation. So if I start moving
my mouse very quickly, you can see that the value
starts going up much higher. So this is essentially
what allows access mappings to control our camera, the direction that
it's moving in, as well as our character. If we go back to our blueprint, you can see that our axis value for move forward and
backwards is an axis value. And if I do a print string here, we connect this up to him. Compile. And I'll remove this
print string so we can see the value just from our move forward
and backwards. Hit play and see
currently it's 0. But if I start moving forward, the axis value has
gone straight to one. And if I go backwards,
you can see it's actually gone to minus one. And that's what tells
the engine whether we're moving backwards or forwards. If we x out of plane editor
and go to Project Settings, and we open up one of
these Access Mappings. Say for example, the
lookup slashed down mouse. You can see that it's
currently not set to. A key is actually set
to on mouse direction. So it's set to mouse Y. The scale is minus one. Now the reason for that is it's just the way that the
camera's working on rail. If I was to set this to
scale one and hit Play. Now when I move my mouse up, I start looking down and my controls are
actually inverted. So typically with mouse
up and down movements, we would use a
scale of minus one to get rid of that
inverted camera movement. But if we were to look at, say, move forward and backwards, you can see that
we've got W and S. Now, w gives us a scale of one that tells the character
when moving forward. S gives a scale of minus one, and that's what tells the character we're
moving backwards. And then we have some
additional key binds here. These are the two arrow
keys on your keyboard, and then we've got the thumbstick
on a game pad as well. Now an important thing
to remember about input events is the
reason these are running inside our ThirdPersonCharacter
is because our third person character is controlled by our
player controller. If we were to start using
these nodes in blueprints, that one controlled by our
controller, they wouldn't run. Now a blueprint that we can use these input events in
is our controller. Now, in the third
person template, there isn't a control. A blueprint will create
a new one quickly. I'm just going to create
a Blueprint Class, select player controller. I'll just call this
example controller. Like that. And if you remember,
we need to set our controller and
our game mode. So I'll go to third-person
game mode and find the player
controller class. Here we'll just change this
to our example controller, will compile and save. Now when we hit play, we will be using our example controller. And I'll open that
controller up. I'll just drag
this up to the top here, go to the Event Graph. And now if I search for
say jump, for example, you can see I can create the jump input action and this will actually
run just fine. And that's because we're
in the controller, are input actions will work perfectly fine inside
our player controller, because the player
controller is what handles are input actions. Next, I just wanted to
talk to you about some of the settings that you'll find if you select an input node, we've got consume input, execute when paused and
override parent binding. So the first one consume
input means that if this is ticked on what we're using an input action inside
our controller. And we had that same event
inside our player character. The jump action in our
character won't actually run. And that's because
our controller is essentially consuming that input and not allowing any other blueprint to run up. So if I was to print a string
here from our jump event. Now when we compile
and hit Play, if I press space, if I go back to my third-person
character here, we will just remove this print strings so we
can see what we're doing like that,
which compile that. And now when we hit
Play, if I press space, you can see that
it's printing hello, but my characters, no
luck with jumping. Now that's because inside
our example controller, we're consuming that input. But if I untick this and
I can pop and hit Play. Now when I press space, you can see that
both my hello text is running and the
character is jumping. So both of those events
in my controller and the character
blueprint or running now. Another one of the settings, if we select the jumping
production here, is execute one paused. You can pause the engine, or if you open up a
menu, for example, if this is ticked on, then the input
will still be able to run even if the
game is paused. And then lastly,
override parent binding. Say for example, our
example controller had a parent blueprint that was different from the
player controller. Then if we had this
option ticked on and that parent blueprint was
also using the input action. Then we're basically
telling the engine ignored the input and
our parent blueprint, use the code that's
connected to us. If we uncheck it, then
this node wouldn't run. The node in our parent
blueprint would run. Lastly, we've got
this other pin here, and this just gives us
a reference to the key that was pressed that
made this event run. So maybe you have multiple keys that would make jump happen and you wanted something
different happened depending on which key
the person pressed, we could drag out and
search for equal. And using this note, you could check is
the key that was pressed equaled to another key. So we could say is
equal to space. And this node would check is the key that was
pressed Space bar. If it is, then it
would return true. We can also get the
name of the key, so we can search with display. We can use getc
key display name. And this will just
tell us in text what the name of the key is
that was pressed that made the jump in production run. So that's gonna be
it for this lesson. In our next lesson,
we'll be looking at the new enhanced input system that comes with
unmoored engine five.
29. Additional Lessons (Enhanced Inputs): Hey everyone. In this lesson we're
gonna be taking a look at the enhanced input system that comes with
Unreal Engine five. So to start with, I'll
show you how to enable it. In this current engine version, I actually have to
enable a plug-in. So I'll go to Edit plugins and I'm going
to search for enhance. You can see enhanced input,
which I can take on. If yours is already ticked on, then you don't need to do this. But for me, I'm
going to take it on. You can get gives
me a warning here, just telling me that
it's still in beta. So I'm just going to hit Yes. And we need to
restart the engine, so I'll do that now. So now I've restarted the
engine and if we check the plugins menu and
search for enhanced, we can see that it is ticked on. Then we're gonna go to Edit
and go to Project Settings. And then here we're going to use a search and we're going
to search for input, or sorry, default input. Now you can see
mine by default is set to player input
and input component. I'm going to change these to
the enhanced player input. And the enhanced
input component. If yours is already
set to those, then you don't need to do this. Now the input system
is what allows us to run code when
the player say, presses a button on my keyboard
or button on my gamepad, or moves their mouse
in a certain way. Now in our last
lesson, we looked at the input system that comes
from Unreal Engine four. This is still present
in Unreal Engine five. So we went through those
in our last lesson, if you want to check that out. But in this lesson
we're going to look at the new system that's been implemented it into
Unreal Engine five. Now the good thing about
this new enhanced system is it's actually
backwards compatible. So if we go back to our
third-person character here, all of these events, these are still using the
older input system from somewhere engine for these
events will still work. So if I hit play, now that I'm using the enhanced input system, but I can still move around. I can still look about these
inputs will still work. But now we can actually create
the new enhanced inputs, which we'll do now, we'll
exit off the play an editor. And we'll start by right-clicking
the content browser. And we'll go to the
input option here, and we'll create a
new input action. Now, this is the equivalent of, if you remember from our
last lesson of going to the inputs option here and
creating a new action mapping. This is the equivalent of that, but now we have
its own blueprint. So whatever we named, this
will be the name of our event. So I'm just going to
call this example input. No spaces. So example
input like that. Now if we open that up, I'm just going to drag
this up to the top here. Now in here is where we can set the settings for our
example input event. So to start with, we
have the value type. Now this is essentially the value that the key
supplies our code with. If it's set to Boolean,
then our key is either pressed or not pressed. But we can change this to say, an axis one day. So this is a single float that represents a
state of our input. So if our mouse, for example, is moving along the x-axis, so that's side to side. This float value will be
either negative or positive depending on the
direction we're moving at him and then the speed
that we move it in, define how large the number is. Now there's also a 2D and a 3D. I'll be explaining
the 2D a bit later. The 3D is a little
bit more advanced, so we won't be going into
that on this lesson. Then next we've got triggers. Triggers define what actually makes our example input run. So if I create a new input, you can see that I've
now got a new index, and here I can choose from
a few different options. Now, these essentially tell
the engine what we have to do with this key binds to
make this example input run. For example, if
we set it to tap, we have to tap the key. This event is bound
to, to make it run. And if we click the
down arrow here, we've got a few settings
for the tap type. We have the tap release
time threshold. So this basically means as long as I press a key and let go of it faster than 0.2 seconds, our example input
event will run. Next. We'll set up an example in our third-person character so we can call our example input. But first we actually need
to create another blueprint. Now, you may have
noticed that in this blueprint we
can actually set a key that we want to make
our example input run. Now, there's another blueprint that actually defines that. We will have to create that. So we'll right-click
and go to input. Then we want input
mapping contexts. I'm going to call mine example mapping context. And
we'll open that up. Now in here is where
we define our inputs. So for example,
our example input. So what we can do is click
the little plus button here. You can see that we've
got these options. We can set an input. So we're going to use
our example and pump. So we're telling it this mapping is for the example input. And then here we can
set which keys we want to actually run that input. So we can click the
little keyboard icon here and I can press
say, L on my keyboard. Or you can click the
drop-down here and select a key and
the options here. So now we've told the engine
that when we press out, we want it to run the
example input event. So now we can go to our
ThirdPersonCharacter and we can create a new event. We can search, for example. You can see we've
got example input. If I create that, you
can see that we get this new input node. Now, this input node is going to look different or
have different outputs depending on the triggers that we have setup in
our example input. So currently we have tap setup. So it's inputs are gonna
be relevant to the top. But if I was to move this and we head back to our
ThirdPersonCharacter. You can see that the outputs
of our note of change. Now, these outputs will do
different things depending on the triggers that you
have set inside your input. So we'll add back in our
tap input or trigger, sorry, and that's the
one at the bottom here. And we'll leave the
settings as default. So we'll save this and we can go back to ThirdPersonCharacter are triggered here will
run whenever we first press down tap button. So for us that's out there. I set it to in our
mapping contexts. And the completed will run
when we lift the key up. So what we can do is we can
add a print string here. We set this to triggered. Spell it right. There we go. And I'll copy and paste this. We'll plug this into, complete it and I'll put
complete it like that. Spell it wrong, but there we go. So now when I compile, we'd expect when I tap out
faster than 0.2 seconds, these would print, but
they actually weren't. And we can see
this if I hit play by tap out, nothing's happening. Now that's because
we also have to make some code changes
inside our character. So to do this, I'm gonna
do an event possess. And if you remember
from our events lesson, this event will run whenever a controller takes control
of this character. So from that we're going to drag out from our
new controller, will do cost too. Player controller. And then from this
we need to get the enhanced input local
players subsystem. Then from that we need to
add a mapping context. Now, this is essentially telling the player controller
that we want to use this example mapping context
that we set up overhead. So we need to set
our mapping contexts to the example mapping context. So now when we compile
it and hit play, if I tap out, you can see that complete and triggered
our printing out. Now the purpose for having
to set the mapping contexts allows you to have different control schemes
depending on what you wanna do. So for example, you may have a character in your
game and a vehicle. Now you may want the
characters controls and the vehicles controls to
be completely different. So what you could do is have a mapping context for your character and then a
second one fuel vehicle. Then in your
character, you could set the mapping contexts using the add mapping contexts node to your characters
mapping context, which could have
all of your inputs for when your players
controlling the character. Then in your vehicle,
a blueprint, you can have the same code, but that could set a vehicle
mapping contexts instead. And then that mapping context, you could have
different controls, maybe for changing gears
and things like that, things that you wouldn't need
in a character blueprint. Now this is a little bit
more complicated than say, the previous input system
that I'm arranging for use. But this system is
a lot more fully featured and once you
get the hang of it, there's a lot more
you can do with it. But just know for
now that if you plan on using the enhanced
input system, you will need this code
in your character to tell the player controller
exactly what mapping contexts
you want to use. And keep in mind, the mapping context
is where you actually tell the input events
what keys can call them. Now, you may have noticed
inside our mapping contexts, we can add multiple keys. So if you want to say
have L and another key, run our example and
put, we could do that. So I could set this to say x. Now, if I hit Play and tap X, you can see that's
also printing out. If I press out, you can see that's also printing
out as well. If we go back to our
mapping contexts, you can see that
we actually have a triggers option here as well
for each one of the keys. Now, if we add a trigger
inside our example input, this will affect all of
the keys that we have. Any keys we add under our
example, input will have to follow the trigger rules that we set up in
our example input. But maybe we don't want to have that in our example input. We wanted certain keys to
have to do certain things. So maybe for example, for L to work with, want to have to tap it. But for X to work, maybe we need to
hold the key down. And if we go, if we click the drop-down
option here and see we've got settings for holding
this key dam. So the main one is
hold time threshold. This means I have to
hold the button down for 1 second before
the code will run. If we hit play now, if I press X, nothing
happens until. One second is happened, and now my trigger is actually running continuously
until I let go of x. You can see complete, It's just run and triggered,
had stopped running. But if I try and tap
my x, nothing happens. If I hold down my owl, nothing happens because
if you remember, we set up the tap rule for my L. So if I tap out, you can see the event it
was running now. So just to summarize
for the triggers, if we exit out of plane editor, if you want triggers
to affect all of the keys that
can call an event, you want to add those
inside the event. So inside here, you set the
triggers here that will affect all of the keys that
you assigned to that event. In the mapping context. If you want individual keys to have different trigger rules, you can do that inside the mapping contexts
under the specific key. And of course, if you
want to add a trigger, you click the Add button here. You want to remove a trigger. You just click the trash
can icon to remove it. Now, we'll remove
the x input for now. You can also have
multiple triggers setup. So if we add one trigger
and I say set this to tap, I can also add a second one, and I could set this to hold. So now our L button
will work if I tap it quickly or if I hold it down
for more than 1 second. And we can test this out. I can hit play. And if I press or
if I tap L quickly, you can see that it's working. Or if I hold it down
and wait 1 second, you can see that now triggered
is running every frame. And if I let go, you can
see completed them runs. Now I'm not gonna go through every type of trigger because
there are quite a few. And if you ever want to
find out what they do, a good way to do that is to just mouse over them in
this drop down menu. And it actually gives you a
reasonably decent explanation of what each one does. Now you may have noticed on our event note here that
we have an action value. Now, depending on
what type of input you've used in the
mapping contexts, this will give us
a value that we can use to control code. So because we're just
using an alkene, this will just run
one when the key is pressed down and 0 when
the key is not pressed. But we can also
change this value inside our example input. Here we can set this
to say Boolean in C that we get this notification every time we change something. If we go back to the
third-person character, you can see that it's now
changed to a Boolean. And this would just be true
when our key is pressed down and false when
it's released. Now we can also use
this value to control things like are looking direction and our
movement direction. Similarly to how
the axis value on the older input system controls our controllers, your and pitch. Those are the directions that our camera is going
to be facing. Now there are a few
different ways to do this with the new system. I'll show you a couple of
ways how to do that now. So we'll start by deleting this event because we won't
be using that anymore. And we'll go to the
content browser. I'm actually going to
rename our example input. I'm just going to rename
it, say mouse up, down. We can open this up. And I'm going to change
the value type to a axis one D, So a float. So the output value
of our event in our ThirdPersonCharacter
will be a float. Then we'll head over to our
example mapping contexts. Now we'll get rid of our current mappings and I'm just going to
create a new one. And we'll set this to
our mouse up and down. And I'm going to set
this input to mouse Y. And mouse Y is our mouse
movement up and down. So we're going to select that. So now we've set our mouse up
and down to a float value. We've set our mouse Y to call that mouse up
and down event. So let's go to our
ThirdPersonCharacter and we'll find the
look up and down. And I'm going to
delete this because that's the old event. And we'll reuse the
pitch note here. So we're gonna do
mouse up or down. You can see under
enhanced action events, we've got our mouse up down. From here. We're going to drag triggered to our Add controller
pitch input. And this will run only
when I'm moving my mouse. And it will take the
action value and plug this in and we'll compile. Now remember, this
is only working because I have this
code up here on the possess that tells
our character that we want to use our
example mapping contexts, which is what we've used to assign our mouse
movement to our event. So what we'll do
now is we'll hit play and I'm gonna move
my mouse up and down. You can see that it is working, but my controls are
actually inverted. So what I need to do is invert the minus and positive values that are being supplied
from my mouse. And the way we can do that
is we can use modifiers. So it will go to our mouse
up and down event here. And in here we've got
a modifiers option. Now, modifiers are a
little bit more advanced, so don't worry too much if you don't get it straight away. But what they allow us to do
is modify the value that's being supplied by our key press or mouse movement, for example. So we'll add a new modifier. If we click the
option here, we've got a few different ones. But what we wanna do is
invert our value output. And the Negate here
was what will do that. So we'll set it to negate. So now when I hit play, if I move my mouse up, I look up and if I move my
mouse down, I look down. That again, is basically
making it so that when the mouse is outputting
a positive value, then negate converts that
to a negative value. And then the other way
round when the mouse supplies a minus value, then the gate turns it
into a positive value, and that's what gives my
camera the correct movement. So now we need a site-to-site. Now my side to side movement, it's still working
because I'm still using that old input here. But if I delete this
and I hit Play now, I can only look up and down. I can't look side
to side at all. So we need to set up a
side to side movement. So we'll do that
by right-clicking. Will go to blueprints or
sorry, we'll go to Input, input action, and we'll call
this mouse left, right. And we'll open that up. We want to set the value of
type to the axis one day. And then we need to go to
our example mapping context. And in here, we need
to add a new mapping. So we're adding a new event. Essentially. We want to set this to
our left and right. We need to set a
key there or mouse movement that will
make this event run. So we want mouse x, so that's our mouse
movement side to side. So we'll select that. Now in our mouse up and down, we used a Negate to invert the values that it
supplies us with. We don't need to do that
with the left and right. So now we'll just go back to
our ThirdPersonCharacter. And again, we'll right-click
and do your mouse left, right, or was it left right. We've got mouse left, right, under enhanced action events. And we'll connect our triggered
up to add controller. And we'll take our
action value and plug that in and compile. So now when I go to my third
person map and I hit Play, I can look side to side and
it's moving about correctly. I can look up and
down. We're now using the new enhanced input system to control our camera movement. Now the enhanced input system actually has another way that we can set this axis
input movement up. Now, instead of having to
individual nodes for this, we could actually
do it with one. The way we could
do that is using a 2D float in our event. So what we'll do now is we'll delete the mouse up
and down event here. We'll just use the
mouse left and right. I'm actually going to rename
this to just mouse movement. So now we can use just one
input action to control. Both are looking side to
side and up and down. So in our mouse movement, we've set our axis, we'll set our access to 2D. So that means that instead of a single float value will
have to an X and a Y value. Then we need to go to our
example mapping context. And we'll get rid of
the top one here. We've already got our
mouse movement here because we had
earlier we've just renamed it and we've
got our mouse X here. But I'm going to
delete that were just completely
create a new mapping. So we'll do mouse move them. So now we need to choose the mouse movements
that will make this mouse movement event run. So we'll go to the option here. We'll search for first mouse Y. Now if you remember our mouse
white as our up and down, and we need to
invert that value. So we need a modifier, and we need to set
this modifier to negate that will invert
the up and down valley. Then we need a new input. So add a new input. This is gonna be mouse x. Now if you remember
before we had individual events for
mouse white and mouse x, now we're doing both of
them in the same event. So now we've added
both our mouse white and a mouse X inputs. Four of them will go to the
ThirdPersonCharacter here. And we're going to delete these events that we
had for previously. So now, instead of having two separate events
for each one of these nodes that control up and down and side
to side movement, we'll right-click and we'll
search for mouse movement. Mouse movement like that. And we've got our new mouse movement event that we set up. So now we'll take triggered, we'll plug this into
control the pitch. And we'll plug this
into your like that. Now you can see we've
got an action value, and this is just a 2D vector. So if we drag out, we can create a break
node and that just gives us access to that
X and Y flow values. So it will use these
values to control our up and down and side
to side camera movement. So our x is always
our site to site. So we'll plug this into
your controller input. And the y is up and down. So we'll plug this into our
controller pitch input. And now we can compile. And we're ready to test
this so we can hit play. And if I move my mouse so I
decide that's working fine. But if I move it up and down, it's still moving side to side. We can move the
camera up or down. Now, the reason for
this is if we go back to our example
mapping context, the mouse white and
the mouseX both just provide us with a
single float value. Now, if we go to our event, you can see we've got
two flow outputs. Now, these two inputs for our mouse up and
down and side to side, or both be trying to
use that x value. But they can't both use it. We need to tell one of them that it needs to
use the y output. So in our mapping context, in the modifiers
for our mouse Y, we're going to add
a new modifier. And we're going to set this to Switzerland input axis values. And if you read the tool tip, it actually explains what it does. It says useful to
map a 1D input, which is what our mouse Y is, it's a 1D input onto the
y-axis of a 2D action. So if you remember, mouse movement is a 2D axis. So our switch is going
to map the axis value of our Y mouse Y to
that second y-value. So we'll use that. So now our side to side movement will be using the X value here. And our up and down
movement will now be using the y value because of that
modifier we've just added. If I hit play, I move my mouse
side to side up and down, and it's all working correctly. So that's just a couple of
examples of how you can use access inputs with the new
enhanced input system. Now there are other types
of modifiers that you can apply to your key
inputs if you want to, you can add them
where we've added on a gate and Swiss or
input axis values. I won't be covering
them in this lesson because there are quite a few. But if you ever want to
work out what they do, you can just mouse over
it and it gives you a brief description of
what each one does. Now we can apply modifiers
to a single-player input, like we have done here
with our mouse Y input. We've added the negate
and the switch input. You can also apply these modifiers inside
our mouse movement. Now any modifiers
we add in here will affect all of the keys that we add to this mouse movement inside our mapping contexts. So it's important to remember that sometimes you
will want to add modifies only to one input like we've done
with the mouse Y, instead of just applying
them to the input type, because that will
affect all of the keys that you bind to that type. So just to summarize, the enhanced input system
allows us to create input actions like
our mouse movement. We can then create
mapping context, which is where we
can set which keys we'll call our new
input actions. Then we can create
those input actions inside our character or
control the blueprints. Then using triggers, we can
choose how that key has to be pressed for the
event to be activated, then modifies allow us to modify the action value that's
provided by that event. For those events to work, we must make sure that we
use the add mapping context. And we can use that by getting
the player controller, getting the enhanced input
local players subsystem. And that allows us to
add a mapping context. Then we set which mapping
contexts we want to use. So we've been using the
example mapping context. So that's what set here. If we don't have this code, then the inputs events that
we've been using won't work. So that's gonna be
it for this lesson. Hopefully you have a better
understanding of how the enhanced input system works now and we will be
using it a little bit more in our future lessons.
30. Additional Lessons (Tags): Hey everyone. In this lesson we're
gonna be taking a look at actor and component tags. Now if you were following along
with our previous lesson, all I've done here is create a new third person template
so we can start fresh. So it start with tags are
basically just an array of name variables that both axes and components have built-in. And because of that, it means we can get an act as tags or components tags without having to cost to another Blueprint. Use Blueprint Interfaces. Then we can use some of the
nodes that are built into the engine to check an
actor if it has a tag. Or we can do something
like getting all of the actors in the world
that have a specific tag. We'll start by going to
the ThirdPersonCharacter and I'll show you where
you can add new tags. I'm just going to drag
this up to the top here. And then our class defaults are just going to
search for tag. And in here you
can see we've got a tags option and it's an array, and it's just an array of
names like we've used before. So if we click the
Plus button here, we can add a new entry. I can set it to say player. We can add new
entries as well if we want to just by clicking
the plus button, if we want to remove entries, we can just click the down arrow next to the textbox
and hit delete. So now we've added a tag to our ThirdPersonCharacter
and that target is plan. Now we need a blueprint that's
going to read these texts. So I'm going to create
a new blueprint and the content browser. And we'll select Actor and
I'm just going to call that trigger, open that up. I'm going to add a box
collision component. I'll just move that
up a little bit here. We'll go to details such
for hidden and untick, hidden and game just so we
can sit and we'll compile. Now like we've done before,
we'll go to the Event Graph. I'm going to delete
the beginning play and the tick nodes, and we'll actually use the actor begin to overlap node
that's already here. Now if you remember,
this node runs whenever something
overlaps our trigger and it gives us access to the other actor that
overlapped the trigger. Now, normally if I wanted to get information that's in my
ThirdPersonCharacter, I'd have to drag out and I've a cost to my
third-person character or set up a Blueprint Interface to retrieve that information. Now, because our tags are
actually built into our actor, we don't have to do this because this is
already an actor pin. So we can drag out
and we can access our tags so I can
search for get tax. And you see I can access
my array of tags. Then this behaves just
like a normal array. We can drag out. We can
use a get node with it. All we can drag out and
we can loop through all of the tags that
are found on our actor. Now act has actually
come with some tags, specific functions
Built-in so we can drag out and we can
search for has tag. We can use the actor
has tag node and this just checks is the
tag that we set here. Or does this accessory have
the tag that we set here? If it does, then that
will return true, and if not, it
will return false. So we can test this out. Now, I can drag out from here. It will actually right-click
and search for print string. We'll connect this up to
our begin to overlap, and I'll plug this into
our Boolean output, will compile, throw one of
these into the map over here, which make it a
little bit bigger. Our to re-scale or to bring
up the re-scale tool, I'll make it a little
bit larger. Hit play. Now when I run
into my cube here, you can see it's returning false because I actually
didn't set the Typekit. So we'll set this to
compile and hit Play. And now when I run
into the keeping and see it's returning true because our player character
has that player tag. Now, because our tag is just an array of names we can add to it during
game play as well. So if we wanted to, we could
drag out and do get tags. And using this array PIM, we could drag out and
use the Add Node. And we could add a
new tag to our plan. So we could add say on fire tag. And then we'll delete these
notes down here for now. Then we could drag out from
our tags again and loop. So we loop through all of the current tags and
we'll print string, the players current tags. So we'll connect this up
to the print string and the array element to the
string will compile. Hit Play. Now when I run
into the box here, It's going to add a
new tag to our plot. And then it's going to
print those tag names out. Just like that. Now we can
also add tags to components. So if we exit out of plane, I just feel hurt and go to
our ThirdPersonCharacter. We'll get rid of this
search for the moment, and I'll select something like the capsule component here. So this is a component and it's the capsule shape that's
in our view port here. And if I with it selected search for tag in the
Details panel in C, we've got component tags. Now, these work exactly
the same as our after-tax is just that these tags
specific to this component. So we can add a new tag, Oh cool, this collision. And I'll compile. Now if
we go back to our trigger, I will have to cast to a character using my
other actor pin here. Because if you remember,
the actor doesn't actually contain the
capsule components, so I won't be able to find it. But if I cast to character. Like that. And we'll delete the
rest of this code. Then from our character, we want to get the
capsule component. And that's down
here at the bottom. Now from this we can drag
out and search for has tag. You can see we've got a
component has tagged note here, and this works
exactly the same as our tag or actor
has tagged node. We set a tag that we
want to check for. Collision. It will return true or false if this character's
capsule component has this collision tag. So it will drag out and other print string and connect
up to here, hit Compile. And now when we run
over our box here, you can say it's returning true. So tags are really handy
way of being able to add a little bit of extra
information to any actor. So anything that's
in the level or any component in those actors. A good example of how
tags can be useful is maybe in the future you
create an AI system. And you want that AI
to be able to tell if an actor is
friendly or an enemy. You can do that using tags. Because all of the actors and your level have tags built-in, you could add those tags to any object and they would
be able to read it. Now, tanks are also useful for getting actors or components. So if we accept our plan as it's her hair and go
back to our trigger. Just going to
delete these nodes. If you remember, we have the get component
by class notes. So if I search for it, get component by class, you can see we've used this node before
and that allows us to get a component from
a specific blueprint. Now, we've also got the get
components by tag node. So if we create that here, we can get all of the
components that are inside of a blueprint
with a specific tag. If you remember, when we set our tag inside our
Capsule Component, these are the tags that
it will be checking for. Then it will output all of the components that have that
specific tag that we set. For example, I could set
this to collision like that. We'll drag out and we'll get
the length of this array. And we'll print
string, the length, drag out from here and do
print string like that. Now when we run
over the trigger, we should see it print out one. Now we can also get the
actors that have attack. So if we go back to our
trigger and we right-click and such what actor with tag. You can see that
we've got the get all actors with tag node. So we can create that.
And this will get all of the actors in our level
that have a specific tag. Now as a warning, this is a pretty performance heavy node, so you don't want to be using
this on tech for example. There's also another get all
actors we've tagged now, if we right-click and such
will get all actors with tag. You can see that
there's a ghetto actors of class with tags. So if we create that, this will do the same thing as
the node up here, but it will limit its selection to a
specific act of type. So maybe we had lots of
actors with a enemy tag, for example, but we
only wanted to get the ones that were the
ThirdPersonCharacter. Maybe you've had
lots of characters that had the enemy tag, but we only get one to get
our ThirdPersonCharacter, we could set this here. Now, this will only return third-person character
blueprints that have the enemy tag. So tags are really handy way
of adding a little bit of information to any object in
the world or any component. So that's it for this lesson. Hopefully you understand
now what tags are used for and also how they
work in the engine.
31. Additional Lessons (Spawning Actors): Hey everyone. In this
lesson I'm going to be talking you through
spawning actors. Supporting actors
is how we create new objects in the
world during gameplay. So it will start with creating a new actor that
we're going to spawn. I'm just going to create
a blueprint class. I'll set it to an actor, and I'm just going to
call this example sphere. And we'll open that up. I'm just going to drag
this up to the top here. And I'm going to add a new
component or search for sphere and we'll
create a sphere shape. I'm also going to enable, if we go down to physics here, simulate physics, that's just so that if we
place it in the world, it'll start rolling
around and have physics. So now we'll go back to the map. I'm just going to
delete this trigger. This is just from
our previous lesson. You don't need to worry about
that if you don't have it. And we'll go to our
ThirdPersonCharacter. And then here I'm going to
create a new input events. So we'll search for
input event one. And if you remember,
this node just runs whenever I press
one on my keyboard. Now to spawn actors
in the world, we use the spoon actor
from class node. Now we've used this
a little bit before, but in this lesson
we're going to go into full detail
about how it works. So starting from the top, we have the class. This is the type of blueprint that we're
spawning into the world. Will be able to select any of our blueprints from
our content browser. If we click the down our hip, nice search, for
example, sphere. In C, we found our
example sphere. It's a little bit difficult
to see because the highlight, but that is that
if I click this, you can see that our class
is now example swim. You can see the name of
the node has actually changed to spawn
actor example sphere. And that actually changes
the return value type. So if we hover over that, you can see that this is now an example sphere
object reference, which means if we had variables, say in our example there, I'll create a new
variable quickly, which called this example. I can poll. Now if I drag out from
the return value, I can just get that
example variable. I don't need to
cast my sphere from this return value because we
have already told the node that we're spawning
that type and it's set the return value to that
example sphere reference. So this can be handy if
maybe you had functions or events that you
want it to cool as soon as the blueprint
is spawned. Then next we've got
the spawn transform. This is the location in the world that the
actor will be spawned. If we drag out, we can
use the make transform note here that allows
us to set the location, rotation and also the
scale of the actor. Now we can also, if
we disconnect this, right-click on the
spawn transform here and do Split Struct Pin. And you can see we can
actually access the location, rotation, and scale right on the node here
if we wanted to. Or we can right-click
again and do recombine, and that will combine
them back together into this transform pen. Now when you're
spawning an actor, it could collide or something else in the world while
it's trying to spawn. So we have collision
handling settings. Now, default will be the
project's default settings which are set inside
the project settings. Then we've got always
spawn ignore collisions. That means that it doesn't
care about collisions. They will spawn at
the location you SAP. We have tried to adjust
location but always bump. That means if it's
trying to spawn at a location that is overlapping, something else is collision. It will try and adjust
the location a little bit so it's not overlapping
that collision. Then we have tried
to adjust location, don't spawn if still gliding. So that does the same thing. It tries to adjust the
location that is spawning out if there's
collision interfering. But if it can't find a location to spawn
with no collision, then it won't spawn this actor. And then we have do not spawn, which means that the
actor will just not spawn if it collides
with anything. For this, I always want
my sphere to spawn. So I'm just going to put always
spawn, ignore collisions. Now the instigator pen
is a pawn reference. Now, we don't actually need to plug this in for
our actor to spawn, but this does allow us to tell the actor essentially
which players spawned up. This can be useful, say, maybe you are spawning
projectiles out of a gun. Then you would want to tell the projectiles
which player spawn them so that when those
projectiles hit another player, for example, that
of a player can then see who was damaging them. There are other uses
for this, of course, not just for projectile's, but that's just an example. Then if we click the down
arrow here, we have the owner. Now again, this is a pen that you don't have to plug in and is usually used for replication
and multiplayer coding. But it does actually allow us to set a variable inside the actor. And if we go to our sphere here, you can search for owner. And that gives us the
ownership of the blueprint. Now, if we've set this when we were spawning the
blueprint, it will, this node will
return wherever we plugged into the owner
pin when we spawned it, we can actually access
the instigator as well. So if I go back to
my examples for her, we can do get instigator and we can get that
variable as well. And this will return
wherever we plug into the instigator pin when
we spawn that blueprint. That's all of the default inputs that come with this node. But we can actually add our own if we go back to our
example, so it here, and I select my example variable in these
settings for it, we can use the exposed
on spawn option. Now, before we took this on, we need to take on
instance editable. Then we can take
on expos on spot. And if we compile and go back to the
ThirdPersonCharacter Blueprint, and we'll compile this as well. We should see that pin a pin. Now it hasn't appeared for me. So I'm going to right-click
the node and do refresh node. You can see that
the pins showed up. Sometimes this happens and you just need to
refresh the node. Sometimes that when you recompile the pen
will just appear. It's just, it's kind of random. But as you can
see, we've now got the example variable input. So we can set this
to true or false. And that will actually
set when the actors spawn that variable
starting value. And we've done this
with a Boolean, but you can do this with
any variable you want. If we wanted to say have a afloat and we wanted this
to be called, say, damage. We could do that and we could set this to incent said it's spool unexposed on
spawn component. Go back to our
third-person character. You can see if I can poll,
it's still not showing up, but I'll right-click
refresh. Now. You see that now we've got
a damaging put pen as well. So now we're actually
ready to spawn our sphere. So I'm going to
connect the pressed up to our example here. And now we need to set a location that we
want to split it up. Now I want to spawn my sphere in the direction that
my camera is looking, say, three meters in
front of my character. So what we'll do is
I'll right-click and do get control rotation. Now this is the
rotation of our camera. I'll drag out from that and
I'll do the get rotation, rotation x vector, and this gets the forward direction
for us, for our camera. Then you multiply that by, we want to change
this pen to a float. So if you remember,
we right-click it. We do convert them and
we change it to a float. I'm going to do
double precision. So here is where we set how far forward we
want our objects bump. So I'm going to do 300. And this is in centimeters, which move this
back a little bit. So we've got some more space. And then we need to drag
out again and do an add. Now we need to add the current
location of our actor, because currently
we're just moving a direction 300
centimeters Ford, but we have no
starting location. So we'll do get actor location. We'll plug this in here. Now, this location
outputted from our Add Node will be
our access location. But Ford 300 centimeters in whichever direction
our cameras looking. So we can plug this in now
to our location up here. Now I don't have to do the
rotation because it's fair. And I'm just going to
leave the scale at one for now so it will compile. And now we can try it out. I'll jump into the level. I'll hit play. And if I press one, you can see that
we're spawning in our sphere wherever I'm looking, but 300 centimeters ahead of us. So that's pretty much how you spawn in new actors
into a world. Next, I'll show you
how to destroy actors. So for that, I'm
going to actually reuse our trigger
from our last lesson. If you don't have
this or this is a, we can delete these
nodes and the code. And here, all this is, is a collision box
that we set here, I've said to hidden is
ticked off, and that's it. So we've got an event
begin overlap here. What we're gonna do is
we're going to check is the overlapping
actor a example set. If it is, then we'll destroy it. So we can drag out and
we can either do cost to example, sphere like this. Now it costs a more useful for when we actually need to get information from a blueprint. Because we don't
actually need to get any information
from this blueprint which just want to check, is it an example where we
can actually drag out and do get class like this. And this gets the actors class. So it gets which type of blueprint that is from
our content browser. And from that we
can drag out when can actually do equals. And we can check is it equals
to the example sphere. And if it is, then we
want to destroy it. So we'll use an f
node like that. And we'll drag out from
other actor and do destroy. And there's a node called
Destroy Actor and that kills or destroys our actor in
the world like that. So this saves us casting. It's a few extra nodes, but casting does take a
little bit of performance. So if we don't have to, then ideally we
don't want to cast. So now we want to try this out. I'm going to go to
the third person map and I'm going to
add in our trigger. I'll put it over here and
just make it a bit bigger. Scale it up a bit. And we'll hit play. And I was born in a sphere. So spawning over here. And I can kick it around because we've got
physics enabled. Just push it into that
box and you'll see that it gets
destroyed instantly. Now, there is another
way to destroy actors. If we go back to our trigger, we can delete this
Destroy Actor node. We can drag out and we can
do set life span like this. Now the set lifespan
node allows us to tell an actor that we
want it to destroy after a certain amount of time. So I can set this to say one. Now, 1 second after the sphere overlaps the trigger,
it will be destroyed. So we can try this
out and hit Play. I can spawn in a sphere. I'll push this into our
box and you'll see that it hasn't destroyed yet and then
it destroys after a second. We could change
this value to say three just so it's a
little bit more obvious. Press one again, push this in. You can see that it's actually
gone out the other side. And then it destroys Because
asked to wait three seconds. So that's it for this lesson. Hopefully you now
understand how to spawn and destroy
actors in the world.
32. Additional Lessons (Code Organization): Hey everyone, In this lesson I'm going to be talking you
through some of the code organization features that are built into the engine. Now, I've just thrown
together some code here. It's just for an example, you don't have to copy
this out yourself. It's just so I can demonstrate the different features we can
use to organize our code. So to start with, we
have reroute nodes. Now, if I double-click
a white line here, we can create these
reroute nodes. Now these allow us
to control where the pen will actually go. And they don't have any
functional purpose. They don't affect how
code is executed. All they do is help you
keep your code tidy up. So you can either
double-click on a white line or a
variable light. So for example, a
yellow line down here. I can double-click on that and I can create reroute
nodes for that. Or you can right-click, scroll to the bottom here, and you can use the
AD reroute note here that creates a new
reroute pen as well. So these can be
handy if you want to get around some code
that's in the way. So for example, I
could add an F no tip. And maybe I wanted this code is run if
something was true, but I wanted some code over here to run it if it was not true. So I could copy paste this
and you put a C there. So instead what I could
do is I could drag from false to my spawn
act to note it, double-click this white
line, drag these down. Now we've got nice
clean looking code. This code will run if it's true, then we'll just sort of zigzag around it and run
this code if it's false. Next we have comments. Now comments are
really important to keeping your code tidy. And also if you're working with other people or comments
are important so that they can easily and
quickly look at your code and see
what parts of it do. So to create a comment,
we can highlight some nodes and hit the
C key on your keyboard. And that will create
a new comment. We can add some text
to this so I could write create player, HUD. So now I can just
look at this comment. I know that these nodes
here create the player hut. Now we can control what
color the comment boxes. So I can change that to say red. I can increase or decrease the font size
with this value here, I can show a bubble. So if we zoom out, it can
be a bit difficult to see the text with the show
bubbled texts on. You can see we get
this little bubble here that rescales
when we zoom out. And if we select the
comment box again, you can see we've got the
color bubble that just allows us to change the color
of the bubble here. Then we've got the
movement mode. Now, if we move the box
with nodes inside it, it brings those nodes with it. But if we want to turn this off, we can change this to comment. And now only the
comment box will move. If you ever want
to edit the text, you can always just
double-click it to this way. Or if you select it, you can change the comment
text over here as well. Another way you can
create comments as if you right-click scroll
all the way to the bottom. There's a add comment option here that you can click and that just creates us a
new comment node. We can also resize the
comment node just by dragging the edge in any direction you want
and you can resize it. You can also use common
boxes inside of boxes. So if I make this a little
bit larger, if I just select, say these nodes, I can add
a new comment to that. And I can add some
texts that so I can do create widget, for example. Another good thing about
comments is if I can do, if I do Control F,
that allows us to search the blueprint
for key phrases. If I search for, say,
create player HUD, which is what is in my comment, you can see that
actually finds the common and it tells me
what's in that comment. If I double-click it, it will take me to that comment box. Next we'll take a look
at the collapsed note. So if we zoom out here
and select this code, for example, if I right-click
one of the nodes, I can select Collapse Nodes. If I click that, we get this new note
here that I can name. So it's cool, this
fire, for example. Now, all that's done is
taken the notes that we had selected and compress them
down into one node here. So if I double-click
this, you can see that all of our
nodes still exist. They're in here and they will still work when we press one, it was still spawn a sphere. It's just that now all of these nodes are contained
in this one node. Now we can add inputs and outputs to our collapse
node if we wanted to, similar to a
function or a macro. So we could add an input, say an execution pin output, and an execution output. We could also add a Boolean
output, for example. And if we open up
our collapse know T, You can see that I input node now has that execution input. We also have that execution
output and our Boolean pen. Now unlike a macro
or a function, we don't actually have to
run these pins for the code inside the
collapse node to run. Because our press one note here is inside our collapse node. It will still run
without us running these pins outside of
the collapse node. Now personally, the
way I like to use these is to group code together. So for example, we have
all of this code here. That's pretty much just for
the character's movement. So we could right-click,
do collapsed node, and then I could call
this a movement. Now all of my
movement code is in one place I can go to,
that's all in here. And maybe I'd have
a collapse node for my shooting mechanics and climbing and various
other things. That way you don't
just have tons of code and your Event Graph. If you ever want to undo having your code in
a collapse graph, we can always just right-click the collapsed graph and
we can do the expand node that will actually
delete our claps node and bring all of our
code back to the Event Graph. Now you may have noticed
the other collapse option. So if we right-click
there's a collapse to function and
Collapse to Macro. Now keep in mind
that these events here can't exist inside
a function or a macro. So if I was to right-click
this and do collapse function, you'll see we get an error, but the code here could actually
exist inside a function. So if I select that and
I do collapsed function, you can see that it
creates this new function, actually automatically adds
the input for us as well. If we open that up, you'll see
that our code is in there. If we go back to our
event graph here, there's also the option
for multiple Event Graph. So you can see
we've only got one. And if we click the
down arrow here, we can actually see our fire
collapse note it also gives us a list of all of the current events in
the event graph. We can create new event
graphs and create a new one. I could call this se
movement for example. In our new movement event graph, we could just copy and paste or I'll cut, so do Control X. And I'll paste this into
our movement graph. And now all of these nodes
are in our movement graph. They still work exactly the same as if they are
in the Event Graph, but now they're
inside a new graph. We can use these to,
again organize your code. Now we can also organize our
My Blueprint panel here. So we'll start with variables. If we click one of
our variables here, we have some options. So this variable
actually comes with a tool tip because it comes with the third
person template. If I select my health variable, for example, in C, we can set description. So I can set this to say
the players current, like that will compile. So now when I hover
over my variable here, it says that the
players current health. And if I go to class defaults
and I find my health area, but which as you can see, if I hover over it, it says
the players current health. We can also categorize
our variables. So if I select my health
variable here again, and I go down to category, we can set a new category. So currently we can set it to default camera or character, but we can create new ones. So if I just select the text and delete that, we
can give it a name. So I'll call this
the health category. Hit Enter. You'll see that now our variable is in its own health category. And we can drag
other variables into that health category just
by dragging it like that. Or if I drag it back out, we can change the category
here now to help. And it just moves up variable
into that category for us. Now, if we go to
our cost defaults, you'll see that we'll have
a new category for health. So we'll compile first. Then we'll go to class defaults. You can see that now we've
got a health category. We've got our
starting health and our health variable
both in there. Now we can also
add subcategories. So if I select my
health variable here, and I go and I click the text, if I click so we still
have health there. But I'm going to add
a vertical line. Now, this is the key in the
bottom left-hand corner above the windows key. It might be in a
different location for other keyboard layouts, but that's where it is for me. If I hold shift and
do a vertical line, I can now write another
subcategory name. Could do, say starting, for example, if I hit Enter, you'll see that now
our health variable is inside the health category, inside the starting category. So we've now got a subcategory. Now, we can also do this
same thing for functions. So if I select my
func new function here that I created when
I collapsed and nodes. We can say a description
for that function. So I could call this,
this is a test function. Function. Now, when
I mouse over it, you can see it reads
this as a test function. So we've got a tool tip.
We can set a cap category. So you can see it's actually got access to our
variable categories. So I could set this to say
at the health category. Now we've got it inside
a health category. And we can do the same
thing with macros. So if I create a new
macro and I select it, you can see I can say Category, say the camera
category for example, we can change its color as well. So if I go to the Event
Graph, we'll drag that in. I'll just add some inputs to it quickly so
it's a bit bigger. So add a few inputs. Now we can actually
change the color. So if I select this, we can change it to be like red. You can see now
we've got red title, but we can set a description
as well if we wanted to. So this is a test, correct? Not correct. If I mouse over
that, you can see it says This is a test macro. Now these are
helpful, especially if you're working
with other people. You can give detailed
descriptions what functions do, and variables do as well. It can also be helpful if you're working in a large
project on your own, because you may have hundreds or even thousands of variables
across lots of blueprints. And you might forget what a variable does or how it works. So it's always good to have a brief description of
what your variables do. Lastly, we can say
blueprint description. So if we go up to cost settings, we can set the current
blueprint description. So you can see at
the moment it says Character Blueprint that
contains movement logic. If we go to the Content Browser and hover over our blueprint, you can see we get
that description when we hover over it
and the content browser, we can change this to
whatever we wanted. We could change this to say the, this is the main character. Now when I compile, hover over it and the content browser, you can see this is
the main character. So that's pretty much
all of the main ways you can organize code
in Unreal Engine, it's really important
to keep your code tidy because it can
really cut down on how much time it takes to fix a bug or add a new feature
into your project. And especially if you're
working with other people, comments and tooltips for your functions and variables
are really important. So that's gonna be
it for this lesson. Hopefully you've learned a
little bit more about how you can keep your blueprint
code nice and tidy.
33. Additional Lessons (Debug Tools): Hey everyone. In this lesson we're gonna
be taking a look at some of the blueprint debugging tools
that come with the engine. So before we get started, I have created a new third
person template project, just so we've got a fresh
start for this lesson. Now, one of the things that
makes blueprints really powerful is how fast
they are to debug. Because we can see what code
is running in real time. We can check variable values easily while the game
is still running. And we can also use
breakpoints to essentially paused the game when a
certain piece of code is run. So to start with, I'll
show you how we can see which code is being run while
we're playing in editor. So I'll hit Play to
enter plan editor. If we press F8, you can see that I've now got control
of my mouse and I can select things in my content browser or
around in the editor. So I'm going to open up my
ThirdPersonCharacter here. You can see that we've
got the editor open, but it's not showing us which code is
currently being run. Now that's because
we need to tell it which blueprint
we want to check. So up here in the
drop-down menu, we have the different blueprints
that exist in the level. So there's only one
ThirdPersonCharacter and I'll level. So we've only got one option. So I'm going to select that. Now. If your windows smaller, if I make mine a bit
smaller like this, you can see I don't have
the drop-down. That's fine. You can just click this
little arrow here. And that will give
you the options that don't fit onto the toolbar. You can see that we can select our character here as well. So now with our
character selected, you can see that the
execution lines on several of our nodes are lit up and that's because they're
currently running. Now. Currently we can
see that several nodes are running inside our
ThirdPersonCharacter. And the reason for
this is these are access input nodes and
they run every frame. Now as well as being able to
see what code is running, we can also check variable
values if we head over to the mouse inputs here
and I take a look at the lookup slashed
down mouse input. We've got an axis value. And if I mouse over
that, we can see the current value, which
at the moment is 0. And that's because
I'm not moving my camera in game at the moment. But maybe I want to
see what this value is while I'm actually
moving my camera around. So what I can do is right-click
and do watch this value. And we get this little
speech bubble that says the current
value of that pen. So if I take control of my character just by
selecting the viewport, I start moving my camera around. You can see that the value on that speech
bubble is updating. So that's a really helpful
tool to be able to see what variables are while
we're playing the game. Now, it does have
some limitations. Usually it won't work
inside a function. So if you're working
inside a function, typically the watch value won't work inside that function. It will only work inside
an event graph or a macro. Now, you may also have multiple
of the same blueprint and your level and want
to see what code is being run in each one
of those blueprints. So if I X out of
play now and I drag in a ThirdPersonCharacter
and just place it over here. Then I hit play and see that it's currently showing us
which code is being run, but only inside the character that we're currently
controlling. What if we wanted
to see the code that's being run inside
our alpha character. Well, if we go to
the drop-down menu now you can see that we've got another character here on
our list of blueprints. Now, you may have hundreds of
a blueprint in your level, so it's hard to
know which one in this list is the blueprint
you want to check. So what we can do is while
we're ejected, we can select, or if we press F8, we can select another blueprint
like our character here. Go back to our ThirdPersonCharacter,
click the Drop-down. You can see that we
actually have this handy selected in brackets, and that tells us which one in the list we have
selected in the level. So we can select that and
then we can view the code that's being run for this
ThirdPersonCharacter. Now, because this character
isn't being controlled, none of its code is
actually currently running. So now moving on, we want to take a
look at breakpoints. Now if I go back to my spawned character here in the drop-down menu so we can see that the
code is running. We know that we've got the
right blueprints selected. What we'll do is we'll
exit out of planets, turn out and I'm going to delete my character here,
so I'll delete that. Now. We're going to create
a begin play note. And I'm just going to drag
out and do a print string. And if we right-click this node, you can see we can
add a breakpoint. And if we do that in C, we get this little
exclamation mark here and we'll compile, just get rid of that
exclamation mark. So this red symbol means that
this node has a breakpoint. Now, breakpoints stop the code or stop the game when
the node gets run. So if I hit play now, you can see that the
games currently halted. And it's telling us, Hey, this node with the
breakpoint as being run. Now, this is really handy
tool if you want to check to see if a piece
of code is being run. Now, if we want to resume
playing and editor, we can just click this
little play button up here and we can take control of
our character like normal. Now, our breakpoints also have a few other features
that we can use. So if we exit out of plane now, I'm just going to add some nodes to print string or add an F. And we'll add a flip-flop node. And from that we'll add, say, a couple of prints strings on each of the outputs, like that. Now, if we play an editor, you can see that our
breakpoint runs. Now. We can resume
like we did before. All we can use the
next frame button, and that will take us through
each node of our code. So if I press this, you can see that it runs
the branch node. If I press it again,
it will take us to the flip flop node. And the reason that true
pen is running is because our condition on our
branch node is ticked on. So it's true. Now with the
flip-flop nodes selected, if I click the next
frame button again, you can see it's actually takes us to a whole new blueprint. We've got these codes here
that we didn't actually write. The reason for that
is our flip-flop node as a macro built
into the engine. So it's going to take us through its nodes in its own code. So we'll go through this and we can select for
each one of these. Now when we get to the
end and I press it again, it takes us back to our
ThirdPersonCharacter out the a input of the flip-flop node and runs the print string node. This is another really helpful
feature of breakpoints. We can go through our
code one node at a time while the game is running to
see what code is being run. Now, there are some other
controls for our breakpoints. If we make our window a
little bit larger here you can see we've got some
additional options. So what I'm gonna do is
restart our plan editor. Now we've gone back to
our original breakpoint. Now we have a few
different options, so we've got step into
next node to be executed. This works pretty much the same as our advanced single frame. Now, if we press this and you see it moves us on
to the next node. Now, if I press this again, you can see it takes us
to our flip-flop node. Now, maybe I don't
actually care what's going on in this node is a node that's built
into the engine. I know that it's working. So maybe I just
want to skip over this node and the
code inside it. What we can do is we can press this next button and that will actually just skip taking us through the code
inside that node. So we can just hit
that and see that it doesn't take us into
the standard macros. We just skip over that and we can use this with
functions as well. So if you have a function
in your code and you don't want to go through every node
that's inside the function, you can just use this
button to skip over it and see what the result is. We can also use this
little magnifying glass to take us to the
currently selected nodes. So if I was looking around my code and I wanted
to see where I was, I could just click this
and it takes us there. So that's how we can navigate while using our breakpoints. And if your window is smaller, so your windows like this, don't forget that you can
always find these settings in the drop-down menu over here if your taskbar
is too small. Next, we're gonna take a look at the blueprint debugger window. So if we go over to the
debug drop-down and click blueprint debugger
in here you can see that we've got this
panel and this gives us some information
about the blueprint we currently have selected. So you can see if I click on the down arrow here next
to my blueprints name, you can see that the variable
that we set to watch, if we go down here, this axis value is
also listed here. So maybe if you've had lots of different values that
you were watching, you could open up
this window and see all of them
appear down here. We can also see the breakpoints. So this is where we have breakpoints in the code
that tells us the node. And if we click it,
it will actually take us to that node. So maybe if you have
a break point in your code and you've
forgotten where you put it, you can always just click this to take you to where
that break point is. Lastly, we have the
execution trace. Now this tells us what's currently running
in our blueprint. So right now you
can see we've got the event begin play
and print string. That's because the
breakpoint is being run. So all of our code
is currently frozen. But if I click the
Resume button, you'll see that we now have
our input axis events, and these are being
run every frame, so these will get
updated continuously. Now, if we exit our plan
editor and hit Play again, breakpoint is now triggered. And if we go over to
the call stack here, we can actually see what exactly made that
breakpoint trigger. Now, currently we're just
running out and begin place. So it's quite easy to see. You can see that it's telling us in the ThirdPersonCharacter, the event begin play in the Event Graph is what's
triggering our breakpoint. But you may have a situation where maybe you have a
custom event that runs some code and that
customer then could be run in lots of
different places. Maybe another
blueprints as well. And maybe that code is being run when you don't
actually want it to, but you don't know which event in which blueprint is
calling it to run. This is where the call stack
can be really helpful. So if we exit out of
plane editor for now, I'll set up an example. So if I create a
new customer vent, creating a custom event, and I'll call this example. I'll connect this up
to our code here. And we'll take up again play note and we'll
call that event, so I'll call it example. Now, maybe we also have other places that are calling
our example event as well. So if I right-click and
search for input events one, and I'll copy and paste this. And I'll set this input
to two, for example, just by clicking the
little keyboard button here and then pressing tube. And we'll also call
that event from these inputs as well, like this. So copy and paste these in,
and then we'll compile. So now when we hit Play
to plan the editor, you can see that our breakpoint
is running and now it's telling us the code that's
calling that breakpoint. We can see that in the
ThirdPersonCharacter, the event begin play. So if we move over
to our event begin play is running in
the Event Graph and that's cooling the example
event in our event graph. And then I'll break
point as being called. But if we resume play and I'll just take
control of my character. You can see in the background there I'm moving
around the camera. If I press one, you can see that our breakpoint is
running and now it's telling us the one
input is being pressed. That's cool. And that's in the Event Graph. That's then cooling our
example customer then, then that is what's
triggering our breakpoint. And then the same
for if I press too, you can see that in
our call stack gets changed to two in
the Event Graph, cooling the example event, and that's in the
Event Graph as well. Now, this can also
work for functions. So if you add a breakpoint
inside a function, then whenever that gets called, it will also show up in
the call stack which events made that
function be run. And this is really helpful in larger projects
because you may have functions and events that are being called in lots
of different places. And if that code is being run when you don't
want it to be, it can be really
difficult to track down where exactly
it's being cooled. So using a call stack
and the breakpoint, you can find very
quickly which events are actually calling that
function or event. Now, the last thing I
find really useful when debugging code is the
print string node. Now we've been using it a
lot in our previous lessons, but I'm going to
show you some of the uses for when
you're debugging code. So what we'll do is we'll
exit our play an editor, and I'm just going to close
our blueprint debugger will maximize our
ThirdPersonCharacter and close the standard macros. Now, print strings
or something I use all the time when
I'm debugging code. We can add them to event chains to know when an event being run, we can use them to print
out variable values. We can also use them
just to provide information on some
of our settings. So for example, say I had
a starting healthfully. So I can call this
starting health. And I could have
a check and might begin placode for example, I could do is greater than 0. And we could do an F node. Connect this up like this. Then we probably want our starting help to
always be greater than 0. So what we can do is if the sign health is
not greater than 0, we can add a print string
and we can just put the starting is 0. Now, if we were to play an editor and are
starting off with 0, if we resume after
this break point, you can see that it's
giving us a warning saying, Hey, you're starting
health is 0. So you can use these to give
yourself warnings about maybe a setting not being correct or something
not being set at all. This can also be really helpful if you're working
with other people. Maybe they're
adjusting a setting and they change it incorrectly. Then when they play an editor, you can have a warning
setup that will tell them, hey, this setting is incorrect,
you need to change it. Now, I'll print string also
has some other options. So if we click the
down arrow here, we've got printer screen. Now, if this is
ticked on, it will be visible in game on
the player screen. We've got print a log. Now, if this is true, it will also be added
to the output log. So you can find the
output login window, then go down to the output
log here and tick that on. You can see we've
got our output log. If I play an editor, now I'm going to
remove our breakpoint here just so it doesn't run. So to remove a breakpoint, just right-click
the node that has the breakpoint on it and just
select Remove break point. Now when we hit play, you can see that our text
is printing out. And if you look in
the output log, we've also got under log
blueprint user messages. We've got those messages
from our print strings. Now we've got a
few other settings for our Print String nodes. We've also got the text color. This will change the color
that it appears on the screen. Then we've got duration. This is how many seconds it
will appear on the screen. Now it's something
I like to do with my Print String nodes is when I'm using them around my code. I also create a variable
called show debug text. And we can poll just to get
our default value shop. Now I tend to connect this up to the printer screen
and print a log here. So now if I want to turn off
all of my prints strings, maybe I'm taking screenshots or video or something like that. I don't want my print
string showing. I can just go into
the blueprint. I can select my show debug
texts on ticket or take it on, and that will turn on or off
all of my prints strings, as long as I have them, this variable connected up to or my print
strings like this. You can also just select all of this do collapse to function. We can call this function
something like error. Texts like that. We'll open it up. So
now in here we've got our print string with
our show debug text. We can drag out from the string to the input node to add a pin. We can do the same with
duration and texts color. Compile this. And now in our Event Graph, we have our error text node. We can say add a message
saying starting is 0. We can set the duration, save three seconds and
the texts to read. And as long as our show
debug text is ticked on, if I hit play, you can see that our text
is showing up here. But now, if I wanted to hide all of my prints strings,
I could uncheck this. And if I was using this function instead of these
Print String nodes, so I had a, maybe
a message here. Let's say example, run. And we could change
the color to blue, and we'll just delete
these prints strings. So now if our show debug texts is ticked
off these white rum. But if we take it on, we can now see those messages. So that's gonna be
it for this lesson. Hopefully you now understand some of the tools that are built into the engine that help
you debug your code.
34. Additional Lessons (Timelines): Hey everyone. In this
lesson we're gonna be taking a look at
the timelines node. So to get started, I'm
just going to create a new blueprint that
we can walk in. So we'll create a blueprint
class set to actor. And I'm just going
to call mine cube. And we'll open that up. I'm just going to drag
mine up to the top here and go to the Event Graph. So just to give you
a brief explanation as to what timeline nodes do, they allow us to change your
values slowly over time. They're really good for
animating things like, for example, a door. Or if you want an actor to move from one
location to another, but you wanna do it
nice and smoothly. So to create a new timeline, we will just right-click
on our Event Graph here and search for timeline. And you can see we've got
an option for Add Timeline. Now, you cannot add
timelines in functions, and you cannot add
timelines in components. So that's just
something to keep in mind when you're
using timelines. So we'll click Add Timeline
and you can see we get this new node here
and I can name it. So I'm just going to call
mine example time line. Like that. Now, we'll be going through all of these inputs and
outputs in a moment. But what we'll do is
double-click the timeline node, and that will open
up this new window that we haven't actually
looked at before. And this is where
we set what values we want our timeline
to be able to change. What we'll do is we'll
create a new track. You can see we can
select from floats, vectors, events, and colors. We'll just start
with a simple float, so we'll add a float
track and we can name it. So I'm just going
to call mine Float, Float, output like that. Now here we have a timeline
that essentially tells us what the value of our
flow output will be. Specific time. So currently we haven't
added any data points yet. So our float value
is just gonna be 0 the entire time that
our timeline plays. But if we want to
add new points, we can, we can hold
Shift and click. You can see I've now got a new
point on my timeline here. And up here we can set the
time that this point is up. So I'm going to set mine to 0. So that's right at the
beginning of the timeline. And then we can set a value. If I was to set this to say one, you can see that I can't
actually see my point anymore. Well, you can do is click
this little button here, and that will bring all of the points that are in
your graph into view. So you can see my points
behind these buttons up that value one and at time one. But we can also add
additional points. And this is what allows us to
change our value over time. So if I shift click
again over here, you can see I've added a new point and we've got a new time. So I'm going to set this to one. I'm going to leave
the value at one, and we will select our
original point over here, and I'm going to
set its value to 0. Now, you can see that
when our timeline starts, the first is at 0, so its value will be 0. But as time moves along, you can see at the top here
we've got the time Valley, once it gets to
the value of one, and that's our time,
the output value of our float will be one. If we go back to our
event graph here, you'll see that we actually have a new output on our node, and that's our float output. And this is what's
going to return that value from our timeline. Now, currently our
timeline will run for five seconds after
it gets told to run. And the reason for that is
up here it says length five. Now if I was to change
this to say one, you can see that our timeline here has gotten a bit smaller. And that's because the
highlighted area is the time that the timeline will run for it because we've
taped for 1 second, you can see that it's now
stopping out 1 second. So now essentially, when we
tell our timeline to play, it will output a value starting at 0, which
will be a float. And then as time moves
on, you can see, if we mouse over, you
can see the value increase as time goes on. And that's because our
second is over here at one. So it gives us a linear
increase in the value. So now we will actually
learn how we can run our timeline if we go back
to the Event Graph here, you can see that we've got
a play and play from start. And this is what tells
the timeline to play. And it will usually play from the beginning of the timeline. So when we tell it to play, it will start from time
0 and it will start, our value is 0 value. Then we have stop, which will stop the timeline for money and its current point. We have reversed,
which will reverse the timeline running at
whatever current point is that. So for example, if our
timeline was at 0.2 seconds of running and then
we told it to reverse. It would reverse from
0.2 seconds back to 0. Then we have reversed from end, which means that
the timeline will reverse from the end points. So odds is 1 second, so it would reverse
from one back to 0. And then lastly, we
have the set new time. And this allows us to
actually tell the timeline what exact time we
want it to run from. Now, when our timeline
is actually running, what will happen is we have
these two output nodes here. Now the update will run every frame that the
timeline is running. So if our timeline is
set to run for 1 second, which it currently
is, this will run for 1 second every single frame. And then once the timeline
has finished running, the finished PIM will run. Now we also have a direction. Now, our timeline
could be running either forward or backwards. To know what way it's running. We can drag out
from our direction and we can use an equals note. We can use equals anion. And here we can just check is it going forward or is
it going backwards? And that would just
return a true or false depending on our value. We can also use a switch so we can drag out and
search for switch. You see we can create a switch node that will
either output forward or backward depending on what our current direction
is for our timeline. Then lastly, we have
our fluid output value. And as I've said before, this will increase slowly
over time as our timeline plays because of
these two points that we have in our graph. So what we'll do now is set up an example of how this works. So we'll just run
play from Begin Play. And I'm going to add a print
string up to our update. So now our print string, every frame that our timeline is playing will output the
current float value. So if we hit Compile,
go back to our map. I'm going to drag in the
cube because currently I don't actually have
one on my level. If we hit Play, you
can see that it's now gradually increasing
from 0 to one. Now I'll show you
how we can actually move the cube using this value. So we'll go back to our cube. I'm actually going to go to
the viewport and just add a cube component so we can see it in the
world and will compile, get back to the Event Graph. So now we want to
actually move our cube. What we'll do is we'll use
a set actor location node. And from that we're going to do a main location or
make vector like that. So I'm just going to be
increasing the Z value. Now, we could, in our
timeline note here, actually set this value to whatever we want our
cube to increase by. So I could set this to say 300. And we can click this
little button to just fit the points and vertically. And we'll go back
to our rent graph. We could plug this straight
into our z value here, plug the update into this. And we want to get
actors current location. From that, we'll
use a break node. Now, all we're doing
here is we're getting its current y and x locations because we want those
to stay the same, but then we're increasing
it z location. So if we hit play now, you'll see that the
cubes slowly moves up as our timeline place. If we wanted to, we could
make this up in a little bit slower so I could
open up my timeline here. I could set the length
to say four seconds. Now, we need to change
our last point here. So we'll need to change
it's time to four seconds. So now our cube or slowly
move up over four seconds. So hit Play. You can see now it's moving up much slower than it was before. Now another way that we can use our float variable to
change the location, and that's a little
bit more practical if we change our n value. So what I'll do is click
the Zoom To Fit Horizontal. So that just brings
the timeline. To show all of our points. I can select our point here, and I'm actually
going to change the value back down to one. So now our first value is 0
and our last value is one. And we'll do the Zoom To
Fit Vertical as well, so we can see that
happening there. So now we'll go back
to the Event Graph. And instead of just
directly telling the cube or output flow
is gonna be it's high. We can use this to move r
cubed between two locations. So it will delete this
code here for now. And we'll drag out from our new location and search for lab. If you remember this
from our vectors lesson, this node allows us to gradually
go from the a location, B location, and that amount
is determined by the Alpha. So 0 would be just the output of this
node would be the a value. And if this was set to say 0.5, then it would be a value
between the a and b locations. And if this was one,
then it would just be the full B location
that's being returned. And if you remember, our float
value now outputs starting at 0 and ending in
one at four seconds. So we can use this to control our lymph node to move our cube between two
different locations. So what we can do now is we can create some active variables. So I'm just going to
call this start actor. And we'll set this
to an actor type. Select that two down
here, object reference, and then we'll duplicate this or just right-click
and do duplicate. We'll call this actor like that and we'll take
on these ice so we're able to edit
them in the level. For our state actor. We want to get its location. And we'll plug this
into the a value. Then we'll do the same
thing with our inductor. Get to location. We'll plug this into the b value here and we'll compile this. So now we'll go to our level and we can create a new actor. So I'm just going to
create a blueprint class. We'll call it an
actor and we'll call this waypoint, for example. Like that, will place one in
the level here and one here. And I'm actually going
to select both of them just by holding Control. And I'll move them
up in the air so we can see them a bit easier. So now when we hit play, what will happen if
we select our cube? We need to tell it the
start and end actors. So I'll set my start
to this guy over here and the end to
the other waypoint. And now when I hit play or cube or instantly appear over it this way point and slowly
move to that end waypoint. So if we hit Play,
you can see that is slowly moving between
those two waypoints. That's happening because
if you remember, our float value is
going from 0 to one. And then I left
node is getting are a location which is our
star actors location. And slowly, gradually
moving that to the end actors location, which is the b value. And then we're
telling our actor to move between those two points. So this is a better way of controlling and
actors location using a timeline node instead
of just manually putting the location
inside the timeline. Now we can also add different types of variable
outputs to our timeline. If we open it up
and we go to track, you can see we can actually
add a vector trap. So I'll click that.
You'll see that we've now got a new
graph down here. I'm just going to
click the arrow next to our float output here just to hide it so we can see
our new track a bit better. I'm going to name this too. Or if you right-click
and select Rename, we can name this to
vector output like that. And if we compile and
go to the Event Graph, you can see that we've now got a vector output on
our timeline node. Now this works exactly the
same as our float value did, is just that we have free float values being
controlled in this one graph, one for our z, y, and x. So if we wanted to, we could gradually
outputs a vector from our timeline
note that starts at one value and
ends and another, just like we did with our float. And if we want to
add new points, we can Shift-click that
adds a new point here. Now if I move this, see that this is
actually in the x value, but our Y and Z is don't have a point and
they're still at 0. So if we want to work in
just one of these values, say I wanted to just
add a value to the z. We can hide the y and the x, and we can Shift-click on our z. And now we can set a z value. Maybe now I wanted
to add a y value. I can hide my z value
and unhide the y value. And you can see I can now
move about this point. And this just makes it
a little bit easier if you have all of these
points is visible, can get a little bit confusing. So now I've got all
of them visible. I can change these
points as I like, and we could add
another 1 12th y value here. And we can move this. And we could do the
same for our z value. Now, the starting values for
each one of these outputs. And if you remember, a vector is just free floats combined. So if we break it, use
the break vector node. You can see that we've
got an X, Y, and Z. Whatever values we sat
in here for x, y, and z, timeline values,
that's what will be outputted at that specific
time on our timeline. And we can use
this output vector just like any other vector. So if I wanted to,
I could actually plug this into my lap node, for example, at the end point. So now when we compile, instead of going to
the end waypoint, It's gonna go to whatever
the output location is from our timeline. If you remember that output
location will actually change because we've got these points in here
that are changing the x, y, and z values
depending on the time. So if we hit Play, we'll see our cube actually moved from the start location. It's going towards 0, so it's going to head towards
that direction. Now, there are other outputs
that our timeline can do. So if we go back to our timeline note here
and open it up, we can actually
have it output and event at certain times
when it's being run. So if we add a new track here, I'm just going to
add a vent track. Now I'm going to hide
my vector output just by clicking the
little arrow here. And we'll rename our event
track to event output. Like that. Now, like our previous output
types for Shift-click, we can add a point
to the timeline. But the only difference is here. We don't, the value here
doesn't actually matter. All that matters is the time. So if I set this to say 1.5, if we shift click again, we can add another
point and we can have this run at say, 2.5. So now what will happen is the event output on
our timeline node will run at 1.5 seconds
and then 2.5 seconds. And if we go back
to our event gra, you see we've now got
a new event output. So if we add a print
string to this, and we'll see this
hello now print at those two times when
our timeline is running. So we've got one at 1.5
and then another 2.5. Then the last output
type for our timeline, if we go back to that node, will hide our event outputs by clicking the
arrow next to it. Again, we'll add a new track and we can add the color track. Now this allows us to output
a color at a certain time. So again, like before, we can shift click on this color down here to add a new point. So I've just added a
new point here and we can move them around
as we like now, because these are white, It's not actually
changing the value. But if I right-click
this at the top, we can choose a color. And I can set this to
say red, for example. Now, at about 2.5 seconds, the output color will be red. But we can move this
around and we can change how severely the color changes depending on these other values. If we move these
around and see now at 2.5 seconds we get
a light red color. If we want to, we can change the default ones that came with our timeline so we
can right-click this one, choose a
different color. We can change this to say, a blue like that. And now you can see we've got
a blue color here that will be outputted at 0.5 seconds. But as time goes along, slowly changes to a
pinkish purplish color and then goes to red. Unlike before. If we go
back to our timeline, you can see that we've
now got a new output. I didn't give it
a name, so we'll give it a name here quickly. I'll call it color. If we go back to
the Event Graph, you can see that now we have access to our color
variable type, and you can plug this into any other color
input that you like. So if we wanted to, we could actually plug this
into our print string. We can plug the color into the text color
here, for example, just hit play and we should see some different colors
for our texts. You can see like purple
and now it's like a red. So that's all of the types of outputs that our
timeline can do. So you can really use timelines to do a lot of different stuff. Now, maybe you wanted
your timeline to actually just go back and
forth to do a loop. I can show you how
you can set that up. So what we'll do is we'll use our inductor location again
here for our B input. And we will take
the finished pen. And actually, we'll
drag out from all directions and we'll
search for switch. When you switch on timeline direction will
connect this up to finished. So now we want to be able to control what our
timeline is going to do, but we don't want
to have to plug these into the inputs here. So what you can
actually do is use a variable to control
this timeline. If we go to the
components down here, you can see we've got
example timeline. We can get that variable. And we can actually use this
to control our timeline. So say later on in our code we wanted
our timeline to play, but without having to
plug into this input, we can use this variable. We can drag out and we
can search for play. You see we can call a
function called play. And this will actually
make our timeline play. To make our timeline
loop back-and-forth, what we can do is we
can use the reverse. So if we drag out, we
search for reverse. We can use the reverse option. So if it's currently
playing forward, we want it to then play
reverse once it's finished. And then if it's
going backwards, we want it to play from start. So we'll just do play. Well, we can do play
from start like that. So now our cube is
going to move from the star actor location to the end and then back to
the end, to the start. And it would just keep
looping and doing that. So we'll delete this note. We're not using that
anymore. So we'll compile and hit Play. We can see our cubits moving
from the start to the end. And now it's moving back
from the end to the start. And this will just keep doing
this now back-and-forth. Lastly, we'll look
at playwright. Now the playwright controls how quickly the timeline
is going to play. So right now our timeline
is set to four seconds. That's how long it'll
take for it to play. Play rate is currently set to one because
that's the default. Now, if we increase
the playwright two, that would make the time
I run twice as fast. So I'll show you
how we can do this. We can take our example
timeline variable, drag out and do set rate. So now we can set the playroom. So maybe I want this
to run twice as fast. So if we connect this
up here to play, and we play now, you'll see that
it's running much faster than it was before. If we increased it
again to say four, it will run four times faster. So now our timeline will
actually complete in 1 second, even though inside
the length is four, because we're telling it
to play four times faster. So if we hit play now
you'll see that it's completing that now in 1 second. Now, there are a few other
settings that I wanted to quickly go through inside
the timeline node. So if we go back to
our queue blueprint and open up our timeline. In here we've got a few
bands at the top that we can use to control what
our timeline does. So for start with, we've got autoplay, and if
we turn this on, it basically means that
we don't actually need to run the play pen for
our timeline to rub. It will just run at the start of the game or whenever
our Cuba spawn. So if I plug in the play
pin and we hit play, now, you can see that it's
automatically playing, even though I'm not
actually telling it to. There's also a loop option. If we go back to our cube
and then our timeline, you can see there's
a loop button. Now, this won't do the same thing as what
we've done down here, where once the cube gets to the end location and then goes back to the start location. This loop will just make the timeline start from
the beginning every time. So if we turn this
on, I'll unplug my finished it and we
compile and hit Play. You'll see that it gets to
the end and then it just starts again from
our start location. So that's a couple of
oxygen she might find useful if you're using
timelines in the future. Now we can also change
the way that our values and our graphs here go
towards each other. So if I select both
of my points here, just holding Control, I
can select both of them. If I right-click, There's a few different options
for the interpolation. So if I set it to say auto, and you see that now, instead of this straight line going
between the values, we have a curve which means that the start value will slowly
increase faster and faster. And then it will slowly
decrease faster and faster until it gets
to its target value. We can use these
little handles here to control how quickly or how slowly the value will approach
the target value as well. So if I select my point
here, move it up like that. I've value will increase slowly than faster and faster until it gets to this point where
it will actually be higher than our n value, because you can see the
line goes above it, but then it will come back
down to our V1 value. Now there's a few
different options. When we highlight these points, you can choose from auto user, break, linear and constant. So constant for example, just a straight line up until the point and then it goes
instantly to that value. We can use linear,
which is the default. It goes from that point to the endpoint at the exact
same rate all of the time. We can use these settings
inside our vector output here. So you can see if I select
both these points here, I've actually
already set to auto, but we can set it back
to linear for example. Or if you want to, we can
take it back to auto. We can control those points like we did before
with our float. And we can do this
with each of our x, y, and z values as well. So we could do the same with
our y-value, for example. We could adjust these to really increase or decrease
however we like. So that's it for our
timelines lesson. Hopefully you have a
better understanding of how they work now and what you can use them for in your projects in the future.
35. Additional Lessons (Sockets): Hey everyone. In this lesson we're gonna
be taking a look at sockets. Sockets or how we
can attach actors to other actors or components
to other components. Now we can add sockets
to skeletal meshes. So that's meshes that can
animate like for example, the mannequin that we've been
using for our character. Or we can add sockets
to static meshes. So those are measures like
the cubes we've been using. So to start with, I'll
show you how we can add a new socket to a skeleton. So we'll go ahead over to
the Characters folder here, then to mannequins meshes. And then here you can see
that we've got our mannequin skeletal meshes and
also the skeleton that the mannequins use. We'll open up the SK mannequin. In here. You can see on the
left-hand side we've got a list of all of the bones that are
skeleton includes. Now, this is where we select a specific bone that we
want to add a socket to. Say, for example, we were
adding a hat to our character. We will want the hat to
follow the head bone. So it will scroll through
and find the head bone which should be near
the bottom here. If I keep going. Here we go. We've got the two neck bones
and then the head bone. So if we select the head bone, right-click and do add socket, that will add us a new
socket to the head bone. If we head over to
the Details panel, you can see we can
rename this socket. I'm going to call my
hat socket like that. Now with the socket selected, you can see that I've got the
option to rotate it here. And if I press W while
selected in the viewport, I can also move the socket. The socket is currently
if you look over here on the Details panel at
zeros are 0 location. That means it's at the exact
location of the head bone, but we can move this so
we can move this up. So now our socket is
above our head bone. What that means is even when
the characters animating this socket will
stay this distance away from the head bone. And this is useful
because if we're attaching a hat to this socket, we would want it to
follow along with the head bone even when
the characters animating. Now if we wanted to
preview what it would look like when it's attached to
a socket. We can do that. So we can right-click
our heart socket here, go down to Add preview
asset and we can actually select a mesh
to attach to our socket. Now keep in mind this
is preview only. So even if we attach
something in here right now, we won't see it in game. This is just for preview
when we're watching animations or in our
skeletal Editor. For me, I'm going
to select just the, select the cylinder here. And you can see that my cylinder is rotated the wrong way. So I'm going to rotate my
socket and you can see in real time or
cylinder rotates. Now, obviously this isn't a hat, is just a cylinder,
but we're gonna be using this as the example. And we can see what
our cylinder will look like while it's
attached to our socket. So now if we go and watch an animation that
uses this skeleton, we'll actually see
this preview and we'll see it move along
with the animation. So if we head back to
the content browser hit, I'm gonna go to the
mannequins folder. Then animations will
go to the money. And we'll take a look at
the jump, for example. We'll double-click that and I'll bring that
animation over to here. You can see that while our
jump animation is playing, R hat is still following
along with our head bone. Now, heading back to our
mannequins skeleton, if we wanted to get
rid of this preview, we can always just right-click, do remove all attached
assets and that will just get rid of all
the previews for us. We can, if we want to add multiple sockets
to the same bone. So if we wanted another
socket that maybe had a different location for maybe
a different kind of hat. We could do that as well. We just right-click
Add a new socket, and that would allow us to add an additional socket
to our head bone. If you ever want to
remove a socket, you can right-click it and
select the Delete option here. Now we can also add
sockets to static meshes. So if we go back to the
content browser here, I'm just gonna go over to the level prototyping
folder and two meshes. We've just got some
simple stack meshes here. But if we open up the
shampooed cubed, for example, in here we've got some
of the details about the mesh and the mesh
in the viewport. And if we go up to the
Windows panel here, there should be a socket manager and their minds ticked on. If yours isn't, you'll
want to click it. And you can see that
for me, it's over here. And this allows us to add new
sockets to our static mesh. So we just click this
little plus button here. We can name our socket. I'm just going to call
mine socket again. Like that. Unlike before, we can
position our socket. We could say set up here. And now, wherever
this mesh moves, this socket will be 90 centimeters from its
center even during gameplay. Unlike in the skeleton, we can also add a preview. So if we go down
to the option set, we can click Advanced and say a previous stack mesh
so we can select the cylinder we had before or the cylinder here and see that we've got that
same meshes we had before. And we can preview what
it would look like when it actually
attaches to the socket. So now you know how to
create sockets and add them to skeletal meshes
and static meshes. Now I'm going to show you
how we can actually use that socket during gameplay
and attach things to it. So it will go back to
our Content Browser, go to the Characters folder,
or to the content folder. Then go to third
person blueprints and we'll open up our
ThirdPersonCharacter Blueprint. Now I've got some
extra variables and a function here from one
of our previous lessons. If you don't, don't
worry about that, we won't be using those anyway. So before we start spawning actors and attaching
them to the sockets, I'm first going to
show you some of the more commonly used
nodes with sockets. So we'll first
start with getting our character mesh from
our components panel. And if you remember, we can just double-click this to
open the viewport. This is our animated
mesh in our character. So heading back to the Event
Graph, I'll zoom in here. We can grab our mesh component. If we drag out from
that and search for get socket location, you can see that we
get this note here. This allows us to
provide a socket name like r hat socket. And if this mesh, so if our character mesh here has that socket using that name, it will return a world
location for that socket. Now we can also use
this get socket location node with
static meshes. So if I added a new static mesh, which doing this as
an example because our character doesn't have
a staggered mesh component. I'm going to add that in. And if I drag that into
our event graph here, I can also plug this
into this note. And now if the stack
mesh that we have set for this component has a socket, we'll get its current
world location. Now, there are a few other
notes that work like this. We can drag out from our mesh
and do get socket rotation. This will give us the
world rotation of whatever socket name we put in here that's on our
character mesh. Or we can delete these nodes, we can drag out and search
will get socket transform, and that will get
the transform of whatever socket name
we set in here. And if you remember from
our transform lesson, we can just drag out from here, use a break node and that gives us access to the location, rotation, and scale
of the socket. Now this also gives us a
transform space option. Now if this is set to RTS world, that means it will get
the world rotation, location, and scale of whatever socket name
we put in here. Assuming that our mesh input
does have that socket. Now if we click the
transform spaces, a few different options,
we can select actor. Now, this will get
the sockets transform relative to the actors
center location. And what I mean by that,
if we go to the viewport, if we select our stake mesh
component that we added, if I move it over here and
imagine this is the socket. The sockets actor relative transform would be this
location that we have here. So if this was a socket
and we were getting that socket's transform
using the actor option here, it would return the
location provided here. Now, the next option
if we go back to our transform node
is the component. Note, now this will
get the sockets transform relative to the component that
it's attached to. So if again, if I go back to our viewport and
we imagine that the stack mesh here is a
socket instead of a component. If I was to attach
this to this measure, you can see that our location
has actually changed. Now this is its
component transform. If I take it back and attach it back to the
capsule component, see that the location
is different because this is the
actor transform. And if we move it
back to component, you see that this is now
the component transform. So again, if our socket or
sorry if our stack mesh was a socket and we were to get its location using
the components space, it would return this value here once it's attached to something
like the Mesh Component. And then lastly,
if we go back to our Transform now we have
the parent Bowman's space. And if we go back to
our mannequin here, we select our bone. Its parent bone space would be the value that we
have set up here. Now, don't worry too much if you found that a bit confusing. Most of the time when
you're using this node, you'll just be using the
World option anyway, because that's typically
the most useful, being able to get the world
location of the socket. Now, there are a
couple of other notes that are useful when
working with sockets. So we'll delete these nodes
now and I'll drag out from our mesh component
variable, will search for it. Does socket exist? And this will just check,
does the socket name that we provide
exist on the mesh or the static mesh
that we plug into the snout and then it returns
a true or false value. If it does. We can also
get a list or an array of all of the socket names exist on a particular
components. So we can drag out and
search for get socket, get all socket names. And this will just provide
us with an array of names. And these will be all
of the names of all of the sockets on this
specific stack mesh. And this will work again with
our skeletal mesh as well. We can just plug that in
like our previous nodes. So now we're actually
going to attach something to a socket
during gameplay. So we'll start just by deleting these notes and hitting compile. We're gonna go to
the Content Browser. I'm going to create
a new actor that will attach to our character. So we'll right-click
do Blueprint class. We'll create an actor,
I'm going to call mine BP underscore hat, or open that up. And then here I'm just
going to add a new Static Mesh Component like that. And we'll set it. Mesh. So we've had over here open
the stack mesh drop-down. And I'm going to set this to the cylinder that we've
been using before, like that, will
compile and save this. Then we'll head back to
our ThirdPersonCharacter. And I'm going to right-click
and search for input event. And we'll use an
input event one. So if you remember this nodes runs whenever I press
one on my keyboard. So the first thing we're
gonna do when we press one is spawn on new hat actor. So I'll drag out
from pressed and social spawn active from class. We'll set the class
to r hat like that. Now, because we're going
to immediately attach our hat to our
character's head socket. We could get away with just
dragging out from here using a transform node and just spawning the hat
at 0 in the world. And then it will instantly get attached to our
character's head anyway. But the thing with this is sometimes for a
couple of frames, you might see the hat
appear in the center of the world and then suddenly
snap to the socket. So what I like to do is
get the sockets current location spawn are at that
location and then attach it. So instead of using
the transform node, we're going to get
sockets location. So I'm going to
get the mesh will drag out and do get socket. We'll use the get
socket transform. We'll put our sockets
naming and this needs to be exactly the same as the socket we created
in our skeleton. So if you remember when
we call it hat socket, we need to use the exact
name of ways that won't find our soccer hat socket. We're going to leave this at RTS world because we want to
get the world to transform. And we'll just drag this out, plug this into spawn
transform like that will set the collision handling to
always spawn ignore collision, because we just want it to
spawn at this location. We don't want it to try and
adjust our extra in any way. So now we're going to
set r hat actor to a new variable just
so we can edit it if we want to later on drag out, we'll do promotes a variable to create a new variable for us. I'm going to call
this hat like that. Now, we've got a hat that will spawn at our socket location
when we play it again. So if we can Paul hit
play and if I press one, you can see that our heart is
spawning on top of my head. But if I move in C, it
stays there because we haven't yet attached
it to our character. We're just telling it to spawn
at that socket's location. So it will exit out
of plane editor and head back to the
ThirdPersonCharacter here. Next, we're actually
going to attach our hat to our character. So to do that, we'll drag out from the mesh component up here, create a new mash
variable, drag out. I'm going to search for
it. Attach. Now there are two attached notes we've got
attach actor to component, which is what we're
gonna be using today because we're attaching the whole heart actor
to a component, which is our mesh component. But we can also attach
components to other components. So for example, if inside R hat, we held a component that we
wanted to attach to the mesh, but we didn't want to attach the entire hat
actor to our mesh. We could use that attach
components, component. But for now, we'll just use
attach actor to component. And we'll connect this
up to the set node. Now we have a target, and this is the actor that
we're actually going to be attaching to our mesh,
which is the parent. So we'll plug that
into the target here. Then we need to set
the socket name. Now this is going to
be the hat socket. Again, this always
needs to be the exact same as the socket we
created in our skeleton. Otherwise it won't attach
the actor to the soccer. Next, we've got the location, rotation and scale rules. Now, this is what the
engine's going to do to the heart actor when I actually
attaches it to the mash. Now, by default
is keep relative, and I'll show you what
that does in gameplay. So if I hit play, I press one. You can see, I can't
even see my hat here. But if I press F1, I look down. You can see that the hats
actually over there, it's attached to the socket, but it's got a
really far distance. And basically that's the
distance that the socket is from the World Center,
which is over here. So if I run my character
over here and I press one, now, we should see the Hat
much closer to the character. This is the relative distance the socket is away from
the center of the world. Now, the next one,
if we go back to our ThirdPersonCharacter
here, is keep world, which if we set these
all up toward the hat, will connect to the socket. The distance away is
currently from the socket. Now, if we use this
and press one now, you actually see it's right
above our character's head and it stays connected
to the character set. But if I was to go back
to my character and under delay, say two seconds. If I hit play now and I press
one and I move over here. You can see that
now it's connected because it's moving
with the animation, but it's that distance that we were away from it
when we spawned it. Then lastly, if we go back
to ThirdPersonCharacter, we can change this
to snap to target. And that will just
make our heart snap directly to the socket. So again, if we can poll, we'll get rid of this
delay here and hit Play. If I press one, you can
see our hats attach to the socket and it stays
there no matter what we do. And if I actually add in
that delay like that. Now before, if we press
one and then moved away, it would stay that distance
away from us book. Once that two seconds that up, it just snaps straight to the socket as you
would expect it to. Now you may want to detach
an actor from another actor, which I'll show
you how to do now, if we go back to the
third-person character here, I'm going to add a
new input events. So we'll search for input event, and I'll add it for input
events 0, for example. Up here, we're gonna get
our hats variable that we created earlier that's being set when we spawn the hat, we can drag out and we
can search for detach. And we can use the detach
from actin option here. And we'll run this
when our 0 is pressed. Now the default
is keep relative. Now, this will do the same thing as when we attach the hat. It will keep the
relative location of the hat from the
center of the world, which isn't usually very useful. So most of the time you'll
be changing this to keep world like this. So when r hat detaches, it will stay in
the location that was when we told it to detach. So if I hit Compile now, hit play, I'll press
one spawner hat. Are we still got that delay? So if I go back to our code
here, we'll just remove that. So it will compile, hit Play. When I press one, you can
see our heart is attached to our character like
it was before I can jump about and
it's still there. If I press 0, you
can see that it's no longer moving with
our character. And it's keeping that
exact location it was when I pressed
0 to detach it. Now it lastly, there
are a couple of other notes that you may want to use when using attachment. So if we go back to our
ThirdPersonCharacter here, we can drag out from r
hat and do get attached. And this will actually get
us the attached actor. So if we use this node while
attached to our character, it would return a reference
to our character. We can also drag out
and do get attached. And this will give us
the attached actors. So this gives us
an array of all of the actors that are attached
to the hat currently. An example of how this could
be useful is maybe when your character dies and
you destroy its body, you want to destroy all of the things that might
be attached to it. This could be a good way of getting all of the
actors that are attached to your character and destroying all
of those as well. Then the last one,
if we drag out and search for gets attached again, you can see that there's get attached parents socket name. And this will tell you
what socket R hat is currently attached to if
it's attached to a socket. Now if you want to find any of these nodes that
we've gone through, you can always
just drag out from a component like the mesh here. If I will make a new
mesh component up here, drag out, you can search for attach to find these
attached nodes. You can search for socket
to find the socket nodes. And you can also search for gets attached to get these
attached modes. Now, one last thing I
did want to mention before finishing this
lesson is you do need to be careful and
attaching actors to your character because they can interfere with your
characters collision. And this can cause
your character to fly off into the air
or have problems moving because that
actor that you've attached to it is
blocking its collision. One thing to make sure when
you do attach things to your character is this a good idea to go through
any of their components? I have collision like an r hat. We've got our stack
mesh component here. We go down and find
the collision presets. Currently it's set
to block or dynamic, which includes our character. So it's always a good
idea to change this to custom and make
sure that **** is set to ignore so that r hat doesn't interfere at all with
our characters collision. So that's it for
our sockets lesson. Hopefully you now understand
how they work and how you can use them in
your future projects.
36. Additional Lessons (Movement Component): Hey everyone. In this lesson we're
gonna be taking a look at the Character
Movement Component. And for those of you
that were following along in our previous lessons, I've just created a new
third person template so we can start from
fresh for this lesson. Now, the Character Movement
Component is built into any character
blueprint type. So here inside our
ThirdPersonCharacter Blueprint, you can see in the
Components panel, we have the Character
Movement Component. Now, the character
movement component is what allows our character
to actually move. And it also provides
us with loads of additional settings
that we can use to adjust how our character moves and what type of
movement it's doing. So if we go ahead and select the Character
Movement Component, you can see over in
the Details panel, we have all of the settings
for that component. If you don't have
the Components panel or the Details panel, you can always turn
them on just by going up to the windows
drop-down here and selecting on the Details panel and also the
Components panel here. Now we're not gonna go through
all of the settings for the movement component because there are quite a few of them, but we will be going through
the main ones and I'll be explaining what they do and
how you can adjust them. If you ever forget
what a setting does, you can always just mouse
over it and it gives you a reasonably good tool tip about what that
specific setting does. So to start with, we
have the gravity scale. Now, this is how much gravity is applied to our character. Fast to set this to
something much higher, like five, and we'll
compile it and hit play. When I jump, you can see my character actually
doesn't jump very high. And that's because
we're applying five times the normal
gravity to our character. Now keep in mind
this gravity value only affects the character, no other objects in the world. Then heading back to our ThirdPersonCharacter and selecting the
character movement, we've got the max acceleration. Now this is how quickly
the character will accelerate up to its
max movement speed. The higher this
value, the faster the character will be
at that accelerating, and the lower, the
lower it will be. Next we have the breaking
friction factor. Now the higher this value is, the faster the character
will stop when we release all of the
movement input keys. Next we have the
crouched half height. Now, this is the height that our capsule component will be when our character
is crouched. And if we go to our viewport, you can see our Capsule
Component here. Now our capsule component
is what the texts, what our character
is running into. Now, when you're crouched, typically you'd want this to be shorter because your
character is crouching down, and that's what
would allow you to move under lower objects. So now we'll head back to the Event Graph and I'm
going to set up a quick example of
how we can tell the movement component
that we're crouching. So if we move up here, I'm going to create
a new input event, log search for input events
C. And I'm just going to scroll up and try
and find that input. So that's here for me. I'm just going to set
it up so that when I press C, our character
Will Crouch. And when I really see
our character walk on crouch, now keep in mind, our character won't
actually play a crouch animation because we haven't set up the
animation side of this. But what we'll be
doing is we'll tell the movement component
that we want it to use the crouch settings to tell our movement component
that we're crouching will drag out from Preston
search for crouch. And we'll select the
crouch function here. And then we'll drag out from
released and search for and crouch like that. Now, these are
functions that are built into character blueprints. If you try to use these
functions and say, just a random act of blueprint, you wouldn't be able to
find these functions. Now there's one
other setting that we need to turn on
and that's actually inside our Character
Movement Component that we need to tell it
that our character can actually crouch in
the searcher we're just going to search
for can crouch. And you'll see under
movement capabilities, can crouch has
actually ticked off. So we're going to take that one. Now we can test
this out in game, so just compile and head to the third person map
and we'll hit play. Now before I hit C, I'm just going to
press the Tilde key, which is the key on the
left-hand side of the wonky. I'm going to search for
show space collision. I'm hit Enter. So now we can see all of
the collision in our level, including our capsule collision, which you can see is that red
outline of our character. Now if I hold down C and see that my capsules
now gotten smaller, That's our capsules half-life, which is 40 centimeters. And if I try and move and see that my
character is actually also moving slower and my
camera is moving down. Now, this is all happening
because we've told the movement
component that we're going into the crouch
movement mode. So now if we head back to the ThirdPersonCharacter
Blueprint and select the movement
component here. And if we search for crouch
and search bar up here, we can find the other
crouch settings. So we have the max
walk speed crouched. Now this is how fast the
character move while crouching, and that value is in
centimeters per second. Now we also have a
setting called can walk off ledgers when crouching. If this is takes off, I can
show you what that does. We'll hit play, run
over to our ledge here. And if I hold seat crouch in C, it won't allow me to walk off the edge while I'm crouching. Now, if we were to
enable that setting, it would allow us to walk
off edges while crouching. So next we'll get rid of
the crowd search and we'll carry on through the
general settings. Now we have the default
land movement mode and default water movement mode. Now, movement modes
or how we tell the movement component which
settings we want it to use. So by default, when on land, we're telling it we want to use the walking settings
which found down here. When in water we want to use the swimming settings which
are found further down. Now when the movement component
is in the swimming mode, it won't suddenly start
using swimming animations. Animations are
handled separately. What it does do is it tells the movement component that we want to use the
swimming settings instead of say, the
walking settings. Now, moving on to the
walking settings, we have the max step height. Now this is how high of an edge that your character
couldn't step up without having to jump. Now by default, this
is 45 centimeters, but maybe you had a
staircase and the character can't just walk up at
normally, you'd have to jump. You may have to increase this
value a little bit to allow the character to step
up a higher height. Next we have the
walkable floor angle. Now this is how steep of a slope our character
can walk up. If you want your character
to walk up steeper slopes, you'd need to
increase this value. Next up we have our
max walk speed. Now this is the maximum speed our character will
go while walking. So if we want our
character to walk faster, we had increased
this value and if we wanted them to walk
slower with decreased, then we have the max
walk speed for crouched. We've explained this before. This is the speed our character will move while crouching. Then we have the Min,
analog walk speed. And this is used for if you have a bucket, a gamepad stick. This is the minimum
speed your character can go with the input
of the input stick. Next, we have the braking
deceleration walking. Now this is how much
deceleration force is applied to the character when you're no longer walking in a direction. So the higher this value, the faster your character
will slow down. Next we have the can
walk off ledges. If this is true, it behaves like R can walk of ledgers
when crouched, it allows our
character to walk off the ledge when walking. And if this is
false, our character won't be able to
walk off of ledgers. Now, scrolling down, we'll go
to the jump settings here. Now we have the
jumps, the velocity. This is how much force is applied when a character
actually jumps. So if we were to set
this is something really high like 2000s. And we can pull, if we hit play and we jump our characters now
jumping really high. Now, heading back to the ThirdPersonCharacter and selecting our
character movement hip, we've got some other
settings for our Jumping. I'm not gonna go
through all of them, but some of the main ones
are the air control. Now this is how
much control over the direction that
your character is moving the player will have, the higher this value, the
more control they'll have. Now, moving down,
we're not going to be covering the network settings in this lesson because
they're far more advanced than what this
lesson is going to cover. But if we keep moving down, you'll find the
swimming settings. And here you can set
the max swim speed. We can set things like buoyancy. And these are only relevant if your character is in
the swimming mode. Then we've got flying. Again. We can set
the max flow speed. This is the speed that
the character will move while in the flying
movement mode. Now, moving down to the character movement
rotation settings, you can see that we've
got a rotation rate. This is how quickly
the character will rotate to face the direction
it's meant to face. So if I was to set this
from 500 down to 50, and we compile and hit play. Now, if I look in the
direction here and I press W, you can see my character slowly rotating to that direction. That setting is how we control. How quick are character rotates. Now we also have a couple of other rotation settings here. Now we've got orientate
rotation to movement, which means the
character will face the direction that
we're moving in. If we turn this off
and fall and hit play, and see that if I start
moving in this direction, our character continuous facing
forward because we're no longer rotating to our
movement direction. Now in our movement component, we also have another
setting called use controller desired rotation. Now if we turn that on, our character will face the
direction our cameras facing. Now we set our
rotation rate to 50. I'm going to turn
this back up to 500. And if we compile and hit Play, you can see that now
whenever I move my camera, our character will turn
to face the direction. Now you can see if I stopped me from my character quickly, our character has
got a bit of delay. Now that's because
of rotation speed. So we could either
decrease or increase this value to make our character rotate quicker to
that direction. Now, something to keep in mind, we've used controller
desired rotation is it doesn't work if you also have orientate
rotation to movement ticked on. If they're both ticked on
here or use controller, desired rotation will not work. So those are most of the
main settings that you'll be adjusting and the
Character Movement Component. But we can also
adjust them in game. So if we want to access what these values currently
are, all change them. We can always get our
Character Movement Component drag out and we can search
for a particular value. Say for example, we were
making a sprint system and we want it to change our
characters max movement speed. We could search for
set max walk speed, and that gives us
access to both our max walk speed and our max walk
speed crouched as well, where we use the max walk speed. I'm going to set the max
walk speed to say 1500. And we'll copy and
paste this node, connect their target backup to our character movement here. And we will create a new input. So it will search for input, then shift, create
a left shift input. When pressed, we want our max
walk speed to increase to 1500 and when released will
change it to say, 600. So now when we compile
and I hit Play, if I walk about without
pressing shift, we've got our normal walk speed. And if I hold shift
down, you can see our character gets much faster. Now heading back to the
ThirdPersonCharacter Blueprint, we can also change what movement
mode or character is in. So again, if we get our
character movement, we can drag out and just
do set movement mode. And we can use the SAT
movement mode function here to change the current movement
mode of our character. So we could set it to
falling or swimming depending on what movement mode we want our character
to currently be in. Now if you remember, we enabled can crouch in our
movement component, but you can actually
also enable and disable other movement modes. So if we scroll right
down to the bottom here, it should be under
the naff movement. We can drop, click the drop-down for movement capabilities. Then here you can
see we can actually enable and disable all of the different types
of movement modes that your character can enter. Now we can also
access whether or not these are enabled or
disabled in our code. So we can search for
can crouch for example. That will allow us to check can our character
currently crouch? Now using our character
movement variable, we can also adjust any
of our other settings. So we could drag out
and search for sets, use controller desired rotation. And we could turn this on or off depending on what we're
doing in our code. We can also increase or
decrease or rotation rate. So we can search
for rotation, rent, and we can set a
rotation rate that we want to use
instead of having to set it inside our character movement
rotation settings here. Now there are settings
we haven't covered in this lesson purely
because there are a lot of them and some
of them are far more advanced and quite
specific to certain needs. But you can find under
most of the categories and advanced option
which will give you access to some
additional information. And if you want to know
what these variables do, you can always just hover over. It gives you a pretty
good explanation as to what they do. The last settings we're
going to cover are actually in the class defaults
of the character. So if we click class
defaults and scroll up here, you should find the use
control of rotation, pitch, yaw, and
roll options here. Now, like the user
controller desired rotation setting that we have
in the character movement, these makes the character face the direction that the
camera is pointing. But the difference is
with these settings, if these are enabled, the character will face
that direction instantly. It doesn't take into account the rotation rate that we have inside our Character
Movement Component. If we scroll down back to
the rotation settings, it will ignore this
rotation rate. If we turn off our use
controller desired rotation, and we head back to our
class defaults, scroll up. We can actually
enable these settings to see how they work in game. So to start with will just
enable rotation Europe. So that's side to side. We'll compile, hit Play. You can see now when
I rotate my camera, the character instantly
faces that direction. Now, typically for a
ground-based character like our
ThirdPersonCharacter here, you would only use
the, your option, but you can enable the other settings in
the class defaults. If we scroll down to find those, you can see we've
got pitch and roll. Now if we enabled both of
these and hit Compile, you'll see when we hit play, we can aim our character in any direction that
our camera is facing. But again, typically
you wouldn't use those two settings for a ground-based
character like this. Now, lastly, like our variables in our Character
Movement Component, we can set those using the
code so we can right-click, we can search will set
controller rotation. We can use set, use
control of rotation, pitch, roll and yaw. And we can adjust those
settings using code. So that's gonna be
it for this lesson. We've covered most of the
more commonly used settings with the Character
Movement Component. So hopefully you now
understand how that works and how you can adjust
how your characters move.
37. Additional Lessons (Audio Effects): Hey everyone. In this lesson we're
gonna be taking a look at how we can play sounds
using Blueprint nodes. Now, Unreal Engine five
has to sound systems. Currently you have
the sound cue system and the Meta sound system. And both of these systems use the same Blueprint nodes to
actually play the sounds. And that's why we're
gonna be taking a look at both of them in
this lesson today. Now, the Meta sound system
is currently in beta, which means we
need to enable it. So we'll head up to
the edit option, go to plugins, and we're
going to search for matter. We're going to take on
the metal option here. If yours is already ticked
on, then that's great. You've already got it enabled. If not, which is
going to take it on, we're going to click yes, and then we need to restart
the engine quickly. So now I'm back in
the engine and I've enabled the metro sound system. Now we can still use the
queue sound system as well. We've just enabled the
metro system as well. And what we can do to make
sure it is enabled is Right-click in the Content
Browser here we can go to the sound option
and make sure that we've got the Meta sound
source option here. Now I'm just going to
explain the main difference between sound cues, metal sounds, and sound waves. So what we're gonna do is
we'll go to the engine folder. And if you don't have that, you can go to Settings
and then go to the content category and make sure show engine
content is ticked on. And that should show
this folder here. Now, with the engine
folder selected, we're going to add a new filter, will go down to sound. We're going to find
the sound wave option which should be down here. We'll take that on. And now currently
we're seeing all of the sound waves that are
built into the engine. If we hover over one, we
can actually play it. So if I hit, you should be
able to hear that sound. And sound wave is
basically the sound file you'll get when you import a
new sound into the engine. Think of sound waves is
just a basic sound file. It doesn't really have many
customization options. Open up one of these
sound waves now which bring us over to
my other screen here, you can see that we've
got some settings here. Mostly under sound is
what you'd be adjusting. There are additional settings, but we're not going
to cover them in this lesson purely because they're a little
bit more advanced. But you can do things like
adjust the volume pitch and you can also turn on or off
looping for this sound wave. But past that, there
isn't a ton of options in here for
customizing the sound. Now this is where it sound cues and Mehta sound system come in. So it will close
our sound wave for now and head back to
the content browser. And we're gonna get rid
of our filter hips. So we'll remove sound wave, will add a new filter
and we're going to look for the sounds pop out. Then we want the sounds
cue option here. And now you can see all of
the sound cues that are built into the engine,
like the sound waves. So we can mouse over one and hit the play and hear the sound, that sound cue or play. If we double-click a sound cue, we can open up the
sound cue editor. Now, I'm not going to be going through all of the
things you can do in a sound cue editor because
there are a lot of them. If you right-click, you'll see there's lots of different nodes that do different things
for sound control. But essentially what a sound cue does is it takes a wave sound. So if we select this note here, you can see it's
actually representing the compiled failed wave. And we can change
that if we wanted to. And then it outputs that
sound to the output node. Any sound that we have plugged into this output is what will be played whenever we play
our compile failed sound cue. Now, if we wanted to, we
could actually have multiple wave sounds in a
single sound cue. And the way we can
do that as if we right-click search
for wave player. We can select that new
node and setting new wave that we want to place so we
could do compile success. Now, maybe we wanted, every time we told this
sound cue to play it to randomly pick between
two different sound waves. We could do that just by
dragging out search for random. And we could plug both
of these sound waves into this random load, then the output into
our output node. And now every time
we play this Q, it will randomly pick one
of these sounds like that. Now there's some things
here on the left. There's the volume multiply
it and pitch multiply. And this will affect all of the waves that are in this cube. So instead of having to go to each wave that our queue users, we could just control the
volume and pitch here. Now we've got the
attentuation settings. Now, I'm not going to be
covering this in detail in this lesson because they're
a little bit more advanced. But basically
attentuation setting blueprints just contain
a bunch of settings that control how far a sound
travels and also how much the sound's volume
decreases over a distance. If you want to see those
settings that are included, that blueprint you can
take on this option here. And I'll actually show you
all of those settings. I'm not gonna go through
these because there are a lot of them and
they're quite complex. If you want to learn more
about these epic actually has some really good documentation
on sound attentuation. So now we've covered
the basic differences between a sound wave
and a sound cue. Now, sound waves again, are just the basic sound file that you important
to the engine. And then sound cues.
We can do things like randomly
picking sound waves. We can adjust things
like the pitch through these nodes here. Now, lastly, I'm just
going to explain how we create a sound cue. So what we can do is if we go to our content browser here, I'm going to get rid
of my sound cue filter just by right-clicking and
doing removed sound cue. And we'll add a new filter. And we'll go to sounds and
we'll just take on sounds. And this is going to show
us all of the sound types. So we'll take this on and we're going to find
a sound waves. So we've got our
camera shutter here. Now to create a new sound cue, you can either just
right-click a sound wave. And in here, you can go up to create cube and you
can click this, and that will create
us a new sound cue. If we open that new sound cue, you'll see, if I bring
it over to the screen. You can see that it's actually
got a camera shutter wave. And that's what we right-clicked on in the Content Browser. And it connects up
to our output for us inside our new
camera shutter q. You can also create sound cues. If we go up to the
Characters folder here, I'm just gonna get
rid of these filters, just right-click and then
do remove all filters. Then we can also create sound
cues by right-clicking. And here go to sound and
you can find the sound cue. And what that will
do is just create an empty sound cue for us. So if we open this up, you'd see that there's
actually no input here because we didn't tell it
what wave we want it to use. And if you want to add a wave, you can just
right-click and search for wave, wave player. And you can set a sound cue here and connect that
up to the output. So next we're going to move
on to the metal sound system. And the metal sound system just replaces the sound cue system. So if we head to the
content browser, I'm going to right-click
go to sounds and we're going to create a new
metro sound source. Now, this is the equivalent
of our sound cue here. So what we'll do is we'll create a new measure sound source. We'll call this new sound like that, and
we'll open that up. So now we've got a
new user interface. It kind of looks similar
to our queue system, but it has a few differences. First, we have an input here, and this kind of works like execution pendens do
inside of blueprints. This will run when our metro
sound is told to play. And then we've got a finished. So we want to run
this once we're finished running
our code and hen, then we have this output
and this is what we plug into for our sound. Now currently it
says our tomato, because our setting for our Meta sound is
actually set to mono. If you want to
change this, which typically you probably do, you want to click this
drop-down and select stereo. And now you can see
we've got an option for our left and right outputs. Now, unlike the
sound cue system, I'm not gonna go
into super in-depth with this system because
if you right-click, you'll see that there are
lots and lots of functions. It's a very big system. But what we will do is we
will create a new Wave plan. So if you right-click and
search for wave Claire, we can use this node to
play our wave sounds. You can see we've got a
play and stop inputs. And again, these work like execution inputs on
a blueprint node. This is how we held
this note to play a sound or to stop
playing a sound. We can set a wave assets. So this is where we set our wave sound that
we want it to play. So we could pick,
say, compiled file. We can set a start time. So if we wanted to, we could start the sound at
different time other than 0. We can change the pitch. We can set it to loop. We can set the time
that the loop starts. And we can set how many
times or how long, sorry, the loop will. Loop for. Loop duration is
set to minus one. That just means if flute is ticked on, it will loop forever. Now, this node has a lot of outputs and we're not going
to be covering all of them, but we will cover how to
actually play this sound. So from our input, we want to run our play
on our wave Claire, this is what tells it to
start playing a sound. And then from our
outputs we want, I'm finished, and
we'll plug that into our metal sound
on finished here. That's what tells
them at a sound that our wave has finished play. Then we've got this
outlet and outright, and we're going to plug
those into our outputs here. For our metal sound. This is what provides a left and right audio output
for our sound. So now if we hit play, we should hear a sound. Now, the difference
with metazoans is we have these execution
pins on the nodes. And here, what we
could do instead of just running the
unfinished output node, is if we wanted to, we could have multiple sounds
play one after another. So we can copy our
wave player here, paste it in down here. Now, when our first
sound finishes, maybe we want another
sound to play so we can connect this finished
pin up too polite. We insert a new sound or set
it to say compile success. But now we want to
connect our left and our parts to these output pins so we can actually
hear the sound. But if we replace them, you can see it disconnects
our first ones. So what we need now is a mixer. So we'll right-click
and search for mixer. You see that we've got lots
of different mixes depending on how many inputs it has, we're going to use
a stereo mixer. So we'll do stereo mix or two. That means we can plug in our left and our right from here, and our left and our
right from here. And it will give us just one
output for left, for right. Then from our finished on our second wave plot will
connect this up to the output. So now what will happen is when we tell our
medicine to play, it will play are
compiled, failed. Once that's finished playing, it will play are
compiled success. And it's going to output the left and right audio
from both these nodes into the mixer and then output the result to our metal sound. And we can test this out
just by hitting Play. You can see both sounds
play one after the other. So that's just a
simple example of the things that you can do with the new metro sound system. Now, there are some
other settings. If we go to the
source settings here, you can see we can set an attentuation setting
just like our sound cues. And again, this is the
blueprint that controls the distance that
the sound can be heard and how much the sound's volume
decreases over a distance. So next I'm actually gonna be
showing you how we can play all of these different sound
types using blueprints. So what we'll do is we'll go
to our ThirdPersonCharacter, head back up to our
content folder here. I'm just going to hide the
content folder for our engine. We'll go to the
third-person folder, open up blueprints, and go
to the ThirdPersonCharacter. And if you haven't
noticed already, I have created a new
third-person project from our last projects are so
we have a fresh start here. So now we're just going to set up example of how we
can play some sounds. So I'm going to add
the game play node will drag out from this and do a timer by events.
From the event pimp. We're going to create
a custom event. We'll call this the sound of M. And just tidy this up quickly. And I'm gonna make this loop, say every two seconds and
we'll take on looping as well. So now there's four main
nodes for playing sounds. If we drag out from our sound event here and
search will play sound. And you see that
we've got play sound, 2D and play sound at location. The difference between
these is play sound. A 2D is really useful for
things like UI sounds. It just plays it on the
local players computer. It doesn't play the sound at a specific location
in the world. Then we've got play
sound at location, which plays a sound at a
specific location in the world. So we'll start with
the place on Tuesday. Here you can see we
can set a sound. This can actually
be a sound wave, a sound cue, or a metal sounds. So if we search for our matter, you can see we can set it
to our new masker sound. We can set to acute sound queue or we can set to a sound wave. Now, it's good practice to
either use sound cues or Meta sounds purely
because you just have more control over
how those are run. But for now, I'm just going
to use our new Meta sounds. So I've searched
for new metro sound and we'll select that again. You could select a
Q if you wanted to. It would run exactly the
same as our metro sound. It will compile
and will hit play. And we should hear
that sound play. And it's paying both
of those sounds. Because if you remember, in our metal sound, we chain those two
sounds together. Now, heading back to our
ThirdPersonCharacter, we'll click this little
drop-down here and it gives us a few settings
that we can use to control this sound
that's being played. We can change the
volume and pitch. We can set a start time. So maybe you had a really long sound and you wanted it to
start at five seconds in, you could put five here, and that's the time that the
sound would stop playing. We have concurrency settings. Now, this is kind of like
the attentuation blueprint. But this type of blueprint
holds the settings for how many of this sound can be played
at the same time. I'm not going to be
going into it in this lesson because it's a
little bit more advanced, but that's what that's
used for and that's the same for owning actor here, those are both used
for concurrency. But for now we can
just leave those blank and our sound
will play just fine. So next we're going
to take a look at the play sound location now. So we'll get rid of
our place on Tuesday. Just compile, drag out
from our sound here and search for Plato sound at. We won't play sound at location. Now this node is going to
have a few extra options. So we can say sound. This time we will pick, say, our cameras shutter
queue for example. We can say location. So I'm just going to use
our characters location. So we use get actor location. Plug that into the location pin. And if we compile, we
should hear that sound play every two seconds.
Just like that. If we head back to our
third person blueprint, if we click the down arrow here, you'll see that we've
got a few new options as well as some of the same
ones from our previous node. We can set a rotation
if we'd like. We can also change
the volume pitch and start times like before. But now we have an option for
the attentuation setting. Now, if you leave this blank, it will use the attentuation setting that you have
set inside the cube. So if you remember it set here, now, this is kind of like
an override options. So maybe this time when
you play the sound, you wanted to use different
distance settings for how far the
sound can be heard. So this is kind of like
an override setting. Typically, if you're
using sound actuation, you want to actually
set them inside the sound cues as opposed
to the nodes here. Then like before, we have
the concurrency settings and our owner actor
pins here as well. Now, both the nodes
we've been using so far, I've just been placed
down to nodes and they're great for just playing a sound
and forgetting about it. But we may want to
be able to play a sound and pause that sound
or lupus or replay it. So there's some other
nodes that we can use for that if we drag
out from our sound now and search for spawn sound in C that we've
got spawn sound 2D, spawn sound at location
and spawn sound attached. Now I'm not going to be covering the spawn sound 2D because it's basically the same
as our previous 2D note. But what we will do is use
the spawn sounder location. Now if we create this, you can see that
we've got all of the same options we had before, apart from we've got a new
one called auto destroy. What this means is once the sound that we set
has finished playing, it will auto destroy
this sound component. So depending on what you're planning to do with this sounds, you may want to turn this off. Maybe you plan on repeating it or pausing it and then
play it again later. You'd probably want to
turn this setting off. Now you can see we've
also got an output, and this is an audio
component output, and this is what we can use
to control their sound. So if we drag out, we can
promote this to a variable. So we can select the
promotes Variable option that will create a new variable
called audio component. And we can set a name. So we'll set it to say a
sound component like that. And now using this sound
component variable, we can call lots of
different functions to actually control the
sound that we've set. So if we get our sound
component variable here, we drag out, we can do things like pause ourselves so we can
search for Set Pause. And we can set whether
or not the sound is paused or if we wanted to
change the volume of our sound, we could drag out and
do set the volume. We could change the volume, multiply using this node. And once we're finished
with our sound component, maybe we just wanted
to destroy it. We can just drag out
search for destroy, and we could use the destroy
component node here. Now there's actually
quite a few settings that we can use with
our sound component. If you drag out and
search for audio, you can actually find all of the audio related functions that can be used with
our sound component. Now the next node we'll cover is the attached sound to node. So if we delete
this code for now, we'll move this up a little bit so we've got a bit more space. We'll drag out from our
sound event and we'll search for spawn sound. And we want the spawn
sound attached note here. Now instead of a location, it actually gives us a component that we can attach ourselves to. This is useful for things
like maybe you had a car, if you had a car engine noise, you'd actually want that
to follow the car around. So you'd want to attach
that sound to a component. We could attach it to say, the mesh component of
our character here. We could plug that in
and now the sound will follow along with
our mesh component. And of course we
can set our sound so we could set this to say be the click
on button Q here. Now if we click the
down arrow here on our spawn attached node actually gives us
a few new options. I'm just going to move these up. So we've got a bit more spacer. We can set a socket to
attach our sound too. So if our mesh had say, a socket on its head, we can set the socket name here and i sound would actually attached to that socket and
follow along with our mesh. Next, we've got the location
and rotation settings. Now, these do something
different depending on the location
type setting here. So if this is set to
keep relative offset, and we would say set
our Z value to 50. Well currently our sound
is attaching to our mesh. So if we go to our viewport, I'm meshes location is right
here and this pivot point. So because we've added 15, the z r sound would
attach to the mesh, but it'd be about this height, 50 centimeters above
the meshes location. Next, if we go back to our node, we have the option for
keep whirled position. Now, if I left this
at say, zeros are 0, the r sound would
spawn at the center of the world and then would
attach to our character mesh. Now, depending on how far away our character mesh was from
the center of the world, safe, for example, it was 500 centimeters in
the x-direction. The sound would always stay 500 centimeters in the x-direction way
from our character, but it would still follow along with our character as it moved. Then lastly, we have
the snap two options. Now, there's two of these. It doesn't matter which
one you select for sounds. So snapped to target will
just mean that the sound is attached to the meshes roots. So right here on our mesh, another new setting
that this node has is the stop when attached
to destroyed. And that basically
means that our sound, if this is ticked on, we'll stop playing when
our mesh gets destroyed. If this is ticked off
than r sound will carry on playing even if the
mesh gets destroyed. Then below that we've just got all of the same settings that we had for our previous nodes that I've been through already. And of course, we've got an output node of
the audio component. And we can set our
audio component variable we created earlier. And we can use all of those same functions that I just showed you with this sound
component variable. Now we can also add audio
components to the blueprints. So if we head over to
the Components panel and we search for audio, you can see it actually
says Audio and then in brackets camera shutter cue. For me, the reason it's doing that is if I go to
the Content Browser, I've actually got that selected. So if I de-select that, we go back to our component
here and I search for audio. We should just see the audio
name so we can click that. That creates a new
audio component. And that component is attached to our character automatically. And over in the Details panel, you can set all of
the things that we've been saying on
these nodes before, we can set the sound
that we want to use. And this can be a wave, a queue, or a metal sounds. So we could choose
our new metro sound. And that will work just fine with our new audio components. We can set things
like the volume, the pitch, we can adjust
the actuation settings. And we can control
this audio component the same way we control to our
audio component down here. We can drag out, we can
pause it, for example. We can remove it
if we wanted to. We could use a destroy. And it behaves
exactly the same as our sound component variable
that we used earlier. So now we can test this
audio component out. I'm just going to disconnect this code here so it won't
be playing anything. And if we compile
it and hit Play, you'll see our audio
sound plays in the Stan Lee because
that component is part of our character. Now, maybe you don't want
the sound to play instantly, you want to play it later on, what we could do is go back
to our ThirdPersonCharacter, select our audio component, scroll down to the auto
activate and tick that off. Now, when we compile
and we hit play, our sound doesn't play. But we could add in some code
to activate that component. So we could right-click
search for input. We can search for
say, input event one. And when I press
one of my keyboard, I want to activate my sounds so we can get audio component drag out and do activate and
use the activate note here. Plug that into our pressed. And now we can
compile and hit play. And when I press
one, i sound plays. Now I can reactivate that every time I want to just
by pressing one. That pretty much covers
the main ways you can play sounds
using blueprints. Now we can also play sounds
inside of animations. So what we'll do is we'll
X out of plan editor. I'm going to head back up
to the content folder here, to the Characters Folder, then to the mannequins,
then animations. Quinn, we're going to open up a run for the animation here. And in here you can see
we've got a notified bar. Now, notifies are basically
pieces of code that can run at a specific
time in an animation. So if we right-click
on our notify bar, we can add a new notified and there's some
built-in ones here, but we're gonna be
using the play sound. If we add that, we
can drag this to any point we want in the
animation, say right here. And now, whenever the
animation gets to playing, at this point, it will play
the sound that we sat. And up here in the Details panel is where we can set ourselves. So this can be again, a wave sound, sound cue
or the new meter sounds. So we can select this cell
it to our camera shutter, or we could set it to
our new metro sound. And that will just play fine. We also have settings for
things like volume pitch, and we can turn
on whether or not the sound follows the mesh. This can be quite important
if you're doing a sound that you want to follow
along with the character, you'd want to take this on. Now when we drag over to our
metro sound here, let's see. I'll play whenever the
animation hits that point. We can also add multiple sound, notifies so we can
right-click and another one hit
click play sound. And now we've got an
additional place and notify. We can add a totally
different sound, say the camera shot acute. So now when we get
to that point, we had that camera shot at play. And then when we
get to this point, are meant to sound plays. So now we're actually ready
to test this out in game. We'll head over to
our map and hit play. So now when I run forward, we should hear our
sounds play at the time of the animation
we sat there like. So, that's gonna be pretty
much it for this lesson. Hopefully you now understand a little bit more about
how we can play sounds and the engine using blueprints and also
animation notifies. Just as a side note, you
might be wondering whether you should use sound
cues or metta sounds. That's going to depend on when you're watching this video. Currently, metal
sounds is in beta, and that's why we have to go to the plugins menu and enable it. But if you're watching
this lesson and it no longer says Beta next to
the metal sounds plugin, you should probably be using
the metro sound system.
38. Additional Lessons (Particle Effects): Hey everyone. In this lesson we're gonna be learning how to spawn Niagara particle
effects using blueprints. So before we get
started for those of you that were following
in the previous lesson, I have created a new
third-person template, just so we've got a fresh
start for this lesson. Now, the third person
template doesn't actually include any Niagara particle
effects for us to use. So we're going to use a free
one from the marketplace. I'm gonna be using Niagara
footstep VFX pack from side arm studio is completely free so you can just pick
it up on the marketplace, select Add to Project, and then select your
project and it will automatically download
everything for you. So once that's
finished downloading, you should find a new folder and your content browser
that we can go to. And in here will be all of those particle effects that
we've just downloaded. So we'll go to the
Niagara Effects folder and go to particle systems. And then here you can
see we've got all of our Niagara particle effects. Now we can select one of
these to have a closer look. I'll open up the dirt
linger, for example. And I'll just bring this
over from my other screen. It may take a moment to compile, so just let it do that
before we can see a preview. Now mine's finished compiling. If I zoom in a little bit,
you can see that we've got a dirt particle
perfect playing here. Now we're not going
to be covering the Niagara Editor in this
lesson purely because it's a huge system that could have an entire course just
focused around it. But what we will be
doing is we'll be using these new
effects that we've imported into our project and we'll be spawning
them during gameplay. So we'll start by going to
the third-person character. So we'll head over to
our third person folder, then blueprints than
ThirdPersonCharacter and inherit, which is going to
set up a timer on Begin Play to spawn
our particle effect. So we'll right-click. So just forget for begin play. Drag out from here and
we'll do timer by them. We'll drag out
from the event pin and search for a custom event. And we'll call this
spawn effect like that. And we'll set it to
spawn every 1 second. And we want this to loop. So
I'm going to take on looper. Now, there are a few
different nodes that can spawn Niagara
particle effects. We're going to be focusing on the two main ones
in this lesson. So if we drag out
from spawn effect and search for spawn system, you can see that
we've got four nodes, but we're gonna be taking a
look at the spawn system at location and spawn
system attached. Now the difference
between these two, notice the spawn system
at location will just spawn our effect at a given location and
it will stay there. Whereas the spawn
system attached, we can use that to attach our particle effect
to something. And if that moves, it will
follow along with that object. So we'll start with
the spawn system at location note
and we'll create. Now starting from the top
we have system template. This is the Niagara effect that we're going to
spawn using this node. So we can click this. You can see that I've
got all of my effects from our footstep asset pack. So we can select one of these. I'm going to select say, the grass effect here. And that means that now
when we run this node, it will spawn the
grass particle effect. It may want to compile some
shaders, just let it do that. Then next we have the location. Now this is the location that our particle effect
will be spawned up. We have the rotation, this is the rotation, it
will be spawn that. And then we have
the scale as well. Now we've got auto destroy. Now what that will do
is it will destroy our particle effect component when it's finished playing
its particle effect. So typically you'd probably
want to have this turned on. We also have auto activate, which basically means that when we spawn the particle effect, it will automatically
start playing. And we have the pooling method. Now, pooling is when
the engine basically stores up a load of
deactivated particle effects. And then when we tell it to
spawn a particle effect, instead of creating a new one, it can reuse a deactivated one. Now for this example, which
can leave this as none. So now we're going to spawn our particle effect at
our characters locations. So we're just gonna do
get actor location. And we'll plug
that straight into our location variable here. I'm going to leave rotation
and scale as they are. Now we can compile and try
this out. So we'll hit play. And if we look at our
characters center here because that's our
characters actor location, you can see we've got
a particle effect playing every 1 second. Now, if I start moving, you'll see that the
particle effects stays where it was
when it was spawned. It's not actually attached
to our character. So what we can do now is we'll take a look at the
attached node. Instead. It will delete our
spawn system at location. And we'll drag out
from spawn effect and search for spawn system. We want to use the
spawn system attached. Now, this has a lot of the same settings as our previous node, but it actually has a
few new ones as well. So starting from the top, we can set our Niagara effect
and the system template. We can pick a different one
this time maybe the leaves. We can also provide an
attached to component. Now, this is what
allows us to specify which component we want to
attach our particle effect to. We could grab the
mesh component here, and we can plug that straight into the attached
two components. This will cause our
particle effect to be attached to our mesh component. Now if our Mesh
Component had sockets, we could specify the socket
name here and that would cause the particle
effects will be attached to that socket. Now we have the
location and rotation. These will do something
different depending on what our location
type is set to. If it's set to keep
relative offset, then if we head to the viewport, if we were to set that value, say 250 in the Z, what would happen is our
particle effects would be spawned at the 0
location of our mesh. So that's the point here
where the pivot is. It would add 50% to its height. So it would still be
attached to the mesh, but it'd be 50 above
the meshes pivot point. Next is the keep whirled
position option. So if we change this to the
keyboard position setting, what will happen now is
whatever location we set here is where the particle
effects will be spawned. And then we attach
it to the mesh. So if your characters say 500 centimeters away from
the center of the world, then the particle effect
would be attached to the character 500
centimeters away. And would keep that 500
centimeter distance from the character
that's attached to. Last, we have the
snap to target. Now, this will cause
the particle effect to snap to whatever
we're attaching it to. So if we're attaching
it to our mesh, it would attach directly
to its pivot point here. So for this example, we're going to keep our set
to snap to target so that our particle effect spawns
exactly on our character mesh. And then after that,
we've just got the same settings
that we had before. We have auto destroy, an auto activate and then we've got the pooling
method as well. I'm going to take on also destroyed because
I actually want my particle effect to destroy after it's
finished playing. So now we can test
this out again. We can hit play and
you can see that our particle effect is playing
at our mesh location now, instead of at the center
of our character. Now, you may want to
be able to control which particle
effect is going to play depending on a variable. So what we can do
is head back to our third-person character here, and we're going to
create a new variable that we can plug into our system template to tell the node which type of
effects we want to play. So we'll create a new variable, I'm going to call mine effect. We can change the variable
type to Niagara system. We want Niagara system
object reference, then we'll compile and
now in the class default. So you can see we can select
any of our Niagara effects. I can pick say, ice for example. Then we'll just drag this
in and connect it up to our system template and compile
it before testing again, we're just going to let the
shaders finished compiling. Now that's finished.
So we can hit Play. You can see that now we can see our ice particle effect
playing instead of our leaves. Now all of the particle effects we've been using a quite short, but maybe in the future
you're working with one that plays for a long time
at a certain point, maybe you want to destroy
it for whatever reason. Well, you can do that as well. If we head back to the
ThirdPersonCharacter, we have an output here, and this is a Niagara
particle system component. And this allows us to
control what we want this particle system to do
after we've spawned it. So we can drag out, we can use the promoter Variable option
that will just create a new variable with the Niagara particle
system component type, as you can see here, I'm
just going to call mine and spawned effect like
that. And we'll compile. Then using this variable we can access some
useful functions. So if I get the variable, we can drag out and
we can use the pause. We can use set post. And this allows us to pause the particle effect
or unpause it depending on which
Boolean values you sat on the note here, we can get whether or not
it is currently ports. So we can do get paused
because of such reports will do is paused and
that will return whether or not the particle
effect is currently paused. And then if we want to
destroy the particle effects, we can just drag out
search for Destroy. We can use the destroy
component node here. Now we can also add
particle effects as components instead of having
to spawn them with a node. So if I say wanted to add a particle effect
to my mesh here, I could go to add
search for Niagara. We could add a Niagara particle
system component to it. With that particle system selected, you can see over here, we can set a particle
system that we want to use. So say the gravel for example, if we go to our viewport in C that when I
went into the view, but it gave us a quick preview. But we can set the
location and it actually shows us what it will look like when it's playing
at that location. This will behave the same as an attached particle effects. So this is attached now
to our mesh component. So wherever I meshed
component goes, our particle effect will follow. And we can also
use this component in the same way in
our event graph. So if we get our
Niagara component, we can plug this into say,
the destroyed component. If we wanted to destroy
that component. We can also use those
pores nodes that I just showed you with our
Niagara component as well. Now another way we can spawn particle effects as using
the animation system. So if we head over
to an animation now, I'm gonna go to characters, mannequins than two animations. And we're gonna go
to the Quinn folder because that's what
our character is. And we'll open up the
Rumford animation here. Now, inhale, we can add
notifies which are kind of like bits of code that run at a
certain point of an animation. These allow us to play sounds or particle effects while
our animation is playing at the exact
moment that we want to play a particle
or a sound effect. So what we can do is we can right-click on our
notify timeline here. Go to Add notified, and you can see that we've got some built-in notifies here. Now we're gonna be using the play Niagara particle effect. So we'll select that
and that creates us a new particle effects notified. And we can drag this
along to have it play anytime that we want
during the animation. So I could put mine
at say 40 here. With that notifies selected. You can see up here we can
set any Niagara system. So I could set this to be, say, our particle effect. Now, if we go over
to our notify here, you should see a dirt
particle effect pair. Now, if yours doesn't, you may get a little
pop-up saying that it's compiling shaders, just allow it to finish doing
that and then you should see your particle
effects play like this. Now currently the
particle effect plays out the characters root, which is right down here. But if we wanted to, we could
set a different location. So we could use the location
offset here to add say, a 50 and the height. So now when we play
the particle effects, you can see it's more up
to the character's knees. Now. We can also set the
rotation offset, which is the particle
effects rotation. And we can also set the scale. We can also attach the particle effect to
a socket or to a bone. So for example, if I wanted my dirt particle effect
to attach to the head, we could set the head bone
hip, select the head. And I'm going to set the
location offset to 0 and the z. So now when we run
the particle effect, you will see that the
particle effect is now running at the head
bone location. We can also add multiple
particle effects. If we wanted to, we could
just right-click Add, notify it and we can add
another Niagara notify. And here we can set this
to another location. We can set a different
particle effect to save the ice particle effects. And we can have both
of those play in this one animation and see that it's currently
playing down here. Now, just a quick tip when
working with notifies. If you've just got one bar here, it can get pretty clogged up if you've got a lot of
notifies and an animation. So what you can do is
click the drop-down here to add notify track. Not just gives you a new
notify track that you can add notifies to like another
particle effect for example. And it will work
exactly the same as adding them to the first track. It just helps you organize
them a little bit better. So now we've got all of these powerful effects
in our animation. We can actually check to see if these are playing in game. So what we'll do is we'll save, we'll go back to our
third-person character here. And I'm actually going to delete the Niagara component
that we just added and we're going to
disconnect. I begin play node. So now our ThirdPersonCharacter isn't spawning any
particle effects at all. And we can test
this out and game. So now when we hit play, we should be able to
run around and see those particle effects that
we added to our animation. You can see the other
particle effects is playing and our ICER particle
effects is also playing. A little bit hard to
see, but you can see it running down there at the feet. So that's just a basic
overview of how to spawn and add Niagara particle
effects to animations. If you're interested
in VFX and how to create new particle effects
with the Niagara system, I definitely recommend
checking out courses that are specifically focused
on that system.
39. Widgets (Overview): Hey everyone. In this section of the course, we're gonna be taking
a look at widgets. Now, widgets or the
type of blueprint that we use to add UI to
our players screen, things like menu systems, inventory systems, health bars. All of those would be
typically done with widgets. Now, which is a pretty
big system on their own. You could probably
make an entire course just for widgets. So in this section we're just going to be going through
some of the basics. You'll learn how to
create new widgets, how to edit their layouts, how to bind things like
variables and functions. To start with in this lesson, we're just going to
be taking a look at the widget UI Layout. We're also going to be learning
how to actually create a widget and then add that
to the player screen. So it start with, we're going
to create a new widget. To do that, we're just
going to right-click in our content browser, then find the User Interface, pop out and go down
to Widget Blueprint. And we are going to select
the common user widget here. And we're going to name it bp
underscore, HUD, like that. Now we need to actually
write some code to spawn that are hot and then
add it to our player screen. So I'm gonna be doing this in the ThirdPersonCharacter
Blueprint, which bring us over from
my other screen here. Now, you can do this inside the player controller
as well if you like. I'm just doing it inside
the ThirdPersonCharacter because that's the blueprint
I have in this template. So what we'll do is we'll right-click and search
for it to begin playing. And from that we're going to
drag out and we're going to search for Create Widget. And that's gonna give
us this new node here. And it's a specific node
designed to spawn widgets. So the first thing
we're gonna do is we're going to set a class and we're going
to select our new BP HUD that we just created. Now we also need to
provide an owning Player, and this is a player
controller type. So what we'll do is we'll
right-click and search for gap player controller. We can just plug this straight
into our opening prayer. So now we're spawning or BP HUD, but we're not actually adding it to the player screen yet. So what we need to do first is create a variable to store
a reference to our HUD. So if we want to
access it later, we can just drag out
from the return value, click promotes variable,
and that's going to create a saint new
BP HUD variable. I'm just going to call mine HUD. And we can drag this up here. Now. We're going to drag
out from the output of the set node and
we're going to search for Add to Viewport. And now this node is going to add to our players viewport. Now on Begin Play, we create our bp HUD, said it's Owning Player
to our players control. We set the variable HUD just in case we want to
access it later. And then we add our head
to our player screen. But if we hit play now, we actually wouldn't
see anything. And that's because
our bp HUD is empty. So we'll head over there now. We'll compile this and
open up our bp HUD. Now we're inside our
bp HUD designer view. And this is where
we actually lay out what our widgets
going to look like. Now, up here on the left,
we have the palate, and this is where
you'll find all of the built-in widget types
that come with the engine. We have things like buttons,
images, progress bars, and lots of others
that we will be looking into in future lessons. Now essentially creating
new widgets for our HUD is done by using the built-in widgets that come
with the engine, things like the progress bar
in the image widget types. We customize them to behave
in a way that we want. So if we wanted to health bar, we're typically use our
progress bar and we would customize it to behave
like a health bar. Or if we're building
a menu system, maybe we could use
the button widget and the image widget
and use them in combination to open up new menus and change
settings, for example. So that's our palette
section here. We also have the
library section. This is new and
Unreal Engine five. This is sort of a
more user-friendly view of the palate view. You can see that actually has
the same options in here. It just gives you a little
preview on the icon here. So it's a bit easier to see what these individual
widgets do. And later on when we create
our own widgets will actually find those
under the user-created. So if I click that dropdown, you can see that there's
aren't, there aren't any widgets here apart
from this built-in one. But when we create
our own widgets, we can actually find
them in here and use them inside of
our other widgets. You can use either
the palate or library view as completely
personal preference. Now, moving on down to the
hierarchy here as well, we can see the current
widgets that are in sidebar widget now currently the random because we
haven't placed any m. But if I was to say grab this
text and just drop that in, you can see that now we've got a textbook that's showing up. We can use these settings here
to toggle its visibility. Now, this is helpful
if maybe later on, you've got a lot of
widgets going on and most of the time they won't
be visible at the same time. You can hide them just like this to make it easier to
work in the widget. Next there's the bind widgets. Now, this has more to do with widget animations and
we're not going to be covering animating
in this course just purely because it's a
little bit more advanced. And what we're
gonna be covering. Next, we've got
our Details panel. Now because I've got my
text box selected here in our hierarchy panel is giving us the settings for our texts. So for example, what I could
change what the text says. So I could say, Hello, This is a test and it
updates our texts. We can set things like color, but if we were using
something else, if I delete my texts
here and added an image, you can see when I
select our image, we actually get
different settings. And that allows us
to set things like an image the size of our
image, and things like that. If at any point any of
these windows are closed, you can go to the Windows
tab just here and you can take any of
them on up here. Next we have the graph view. Now this is where we put
code that's gonna be run that's relevant
to our widget. If we head over to
the graph view now, you should notice that
it looks pretty much the same as the blueprint editors that we've been working with. You have your mike
Blueprint panel. Here you have the functions, macros, variables, and
event dispatchers. We have our Details panel, which depending
on what I select, if I create a new variable, for example, you can
see it gives us all of our variable details as
you would expect it to. And of course, if I drag this variable when we
can get and set it, we can run code normally as if this was a
normal blueprint. Now we do have a couple
of different notice, so we have the event
construct that you can see. It's kind of grayed out. Now, if we delete this
and just search for it, we can search for
Event Construct. You can just create it normally. Now, this works pretty
much like a begin playing out it run whenever
our widget is created. Now we also have this
event pre-constructed. This will actually one every time we can pull the blueprint. So to give you an example, Maybe we could hide our image
which other week raise it. You notice that we actually have an image variable here
in our variables. And this is referring to the image that we added
to the blueprint. And the reason we have
that accessible in our Event Graph is if we go back to our designer,
select the image. You can see that here it's
ticked on for is variable. So that means we can access this image fruit
code via a variable. So what we'll do is
we'll grab that image, will drag out one just
to set visibility. We'll connect this up to our
preconstructed like that. So when I can pull it out, we can see it's set to Visible. So if I go to my designer,
we can see our image. It's just a white
image right now. But if we go back to
the Event Graph and I change this to hidden, now when I compile, go
back to the designer, you can see it's no longer visible because we
set it to hidden, and that event actually runs every time we compile our code. Now, our widgets can actually cool code inside
our event graph. So what we can do is we'll go
back to our designer here. I'm going to delete the image
for now and we're going to take a button and
drag it onto our Hud. You can either drag
it just straight into here or you can drag it
down to the hierarchy. It does the same thing. So we'll just drag it in with our buttons selected
in the Details panel. If we scroll down to the bottom, we have some of
these event options. Now if we click
this plus button, it will actually create us a new event and the event graph. So maybe I want this
button to run some code. When it's clicked, we can click this little
plus button here, and that actually creates us a new event inside
the event graph. Now, this event will run whenever we press that
button during gameplay. Now, something to keep in
mind when coding in widgets, it's good practice not to put gameplay code
inside a widget. Really, you should just
be having your widget to display information and
then take input from, say, things like button presses. And then that widget should
tell other blueprints, like blueprint actors or your character blueprint
what was pressed, you shouldn't actually
be doing any of your gameplay coding
inside of a widget. So for example, if this
button killed my character, for example, we could
just right-click search, forget player, character, drag out from here and
run Destroy Actor. Now, when I press that button, it would destroy my character
and this would work fine. But it's not particularly
good practice to do this. What really you should do
is we should cost too. Or third-person character like this will delete the
destroyed actor node. And then inside our
ThirdPersonCharacter, we should actually have
a separate events. So I'll create a new customer. Then we can call
this kill player. Then this would
run Destroy Actor. Like that. We'd go back to our HUD, drag out from our
ThirdPersonCharacter and we would call that events would call kill player. So now our widget isn't actually the blueprint that's
running the gameplay code. It's just taking the
buttonClicked input. It's telling the
ThirdPersonCharacter, Hey, you need to run this event. Now, this doesn't
matter too much for coding in
single-player games. But later on, if
you want to branch out into multiplayer coding, this is a very important
practice to follow. You don't want widgets to
actually run any gameplay code, only to tell the gameplay code inside of other blueprints
what's happened. Now. Lastly, if we
actually compile our HUD, you'll see we get some errors. That's just because we
deleted our image in the Designer View and
replace it with the button. And if we move up
here, we've actually still got a reference
to that old image. So what we can do is
just delete these nodes, compile, and that'll
get rid of the arrows. Now we've finished
for this lesson. In our next lesson, we're
going to take a closer look at the Designer View
and then how we can control the
layout of our widget.
40. Widgets (Layouts): Hey everyone. In this lesson we're gonna
be learning how we can actually control
a widgets layout. So to start with,
in our last lesson, we created this BP HUD and we added some code to
our ThirdPersonCharacter, which basically creates
that HUD and then adds it to our players
screen on Begin Play. Now we also added in our last lesson to the
BP has a button widget. Now currently that's taking
up the whole of our bp HUD. So what we're gonna
do is select it in the hierarchy liter. Then we're going to compile and that's gonna give us a warning. So we'll head over
to the graph view, which is going to
delete this code here. And the reason we're getting
this warning is because this event is
supposed to run when the button we just deleted is pressed and it no longer exists. So that's why we're now
getting that warning, will delete this and compile. Now we're going to head over to the design of view and
we're actually going to take a look at some of
the panel types of widget. So we'll head over to
the palette tap here, and I'm going to select panel. And in here we have a few
different types of panels, and these are useful for controlling layouts
with widgets. But we're going to start
with the canvas panel. So we're just going to
drag this into the top of our widget hierarchy
here and just release that. And now we have a canvas panel. And you can think
of a canvas panel. It's kinda like a representation of the players whole screen. If we were to add something
like a button here, and we can just drag that in and release it onto
our canvas panel. If we compile and hit play, we should see our button
here on our players screen. So now we'll X out of plane editor and head
back to our hardware. Now, you may have
noticed we have this button down
here that we can drag and that allows us to
resize our viewport here. Now, it's important to keep in mind all this is
doing is changing the preview of our widget so we can see what our HUD
would look like, say at this resolution, or maybe a different
resolution like down here. But this isn't actually changing
the size of our widget. All this is doing is
changing the preview. We can see what our
widgets actually look like at specific screen sizes. Another way you can do this is with the screen
size option here, and this just gives
you a bunch of previews for different devices. So if you're working
on a mobile device, you could pick a
device in here to preview it's exact
screen resolution. But for most people,
you're probably going to be using a ten ADP monitor. So we can head over to
monitors and select the 21.5 to 24-inch monitor. And that's actually going to
change it to ten ATP for us. And you can see that
resolution down here. Now, our canvas panel
is actually kind of special compared to
our other panels. When we drag things like
buttons or images into it, we can actually drag them
around and move them to different places with
inside the canvas panel, we can also resize them. So if I want to make
my button bigger, I can just drag it out
and make it larger. Now because I have
my button selected and it's a child of
our canvas panel. And what I mean by child is it's directly contained
inside our canvas panel. As you can see here
under our canvas panel, we have our button, which is a child of
the canvas panel. Now because of that, we also have some settings
in our buttons, details that are exclusive to it when it's inside
a canvas panel. To start with, we
have anchors and I'll explain a little bit
about that in a moment. But we also have the position x. So this is a side-to-side
possession, possession y, which is it's up
and down position, then we have its size. So this is its size and width
and its size and height. Now, our anchor is basically the center point
for this widget. So if I was to set this to
0 in the x and 0 in the y. You'll see it goes up to our top left-hand corner because currently that's
where it's anchors. But if I was to change this
anchor to say the center, you can see that it's
position x and y. It has actually gone up. And that's because now it's 0 position would be in
the center of the screen. So if I was to set
this to 0 again, you'll see that widget actually goes to the center
of the screen. Now, the alignment
is kind of like the pivot point position
for our widget. So currently 00 means it's going to be in the
top left-hand corner. If I change this to 0.50.5 or center of our widget
is now at its center. And that's why the
widget has now moved into the center position, even though it's x and
y position is still 0. Then we have the
size to content, which I will explain
later on in the lesson. We have the z order, which basically
controls if we have two widgets overlapping
each other, the one with the highest
see order will be on top. So if I grab another
button here, will have to zoom in to see it. If I drag this over
the top of our widget, you can see that
it's actually over the top of our lower widget. But if I select my lower widget and I increase this to one, you can see that now it
goes over the top of this. We're jet because
it's the order is 0. Now, moving down in
the Details panel, we have some appearance options, and these are going to
differ depending on which widget you currently have. So because we're in a button, if we account for the style, you will see we got options for normal hovered and pressed. Now, these are what the
button is gonna look like when it's just normal, nothing's happening to it. Then when the mouse
is hovered over up and then when it's actually
being pressed down. And if we open up one of these, say the normal option, we can change things
like the image or tint, or whether it's drawn as a rounded box or just a normal
box. And you see that now. No longer has the
rounded corners, or we can change it as tense. So I could change
this to say be red. And you can see now it's
highlighted in red. Now as you can see, there's
lots of different options and every type of widget
has different options. So I'm not gonna go through
all of these settings. If you want to find
out what they do, you can mouse over them and it gives you a little tool tip. Or you can just have
a play about changing colors and sizes and
things like that. But just as an overview, when you select a widget, this is where you'll find all of its settings for how
it actually looks. So next we're going to actually delete
these buttons here. We're going to take
a look at some of the other panel options we have. So we're going to start
with a vertical box. So if we just drag that in, I'm going to zoom out
a little bit more. Now, as you can see, this
is just an empty widget. There's no visual
appearance for us. But what we can do is
add other widgets to it. If I scroll up and I
grab, say the text, I can either just drag it
on top of the vertical box here or we can drop it
over it in the hierarchy. So we can drop that in. You can see that it's now
added our texts for us here. Now, because we haven't added our texts to the canvas panel. When I select it, I can not
move it around or resize it. Like if I added some texts
directly to the canvas panel. And the reason for that is our
vertical box is what takes control of the size of our text is going
to be its position. So if we were to add another
text into our vertical box, see that now it starts
stacking them vertically. And this is the key
feature of a vertical box. As we add new widgets to it, it will add them in
a vertical stack. Now, if we select our
vertical box here, you can see that
currently it's this size. If we move it about, We
can still move it about in our canvas panel because it's attached to
the canvas panel, whereas the text is then attached inside
the vertical box. But if you look at a toolbox, isn't actually the same
size as our texts are. Texts like leaks out of it. Now, this is where the size of the content option comes on. If I take this on, you can see that now my
vertical box has gotten larger and now is the size of
whatever we put inside it. So this is the main feature
of the site's content. Any widget that has
children widget inside it. If you tick this option
on for that widget, it will resize itself to just be the size of whatever
widgets are inside it, like our vertical box. Now, if we select
some of the texts that's currently inside
our vertical box and we scroll up to the top here you'll see that we've now got settings that are
called vertical boxplot. That's instead of the
canvas panel slot that we had when we put our text just directly inside
the canvas panel. Now, these are some of the
controls we can use to adjust our texts while it's
inside a vertical box. So to start with,
we have padding. Padding is basically how
much space there is between our texts and the outside
of the vertical box. So if we change this to say ten, what it will do is it will give our texts ten pixels between its edge and the edge of the vertical boxes
you can see here. Now it's done it in
all directions for this text because I've just
put ten in the top hit. But if we click the down arrow, we can actually specify left, right, top, and bottom. Next we have the
size and alignments. Now currently, our vertical
box will just change its size to whatever
is inside it. Now, to really test
out the settings, we're going to have
to disable that. So we're gonna turn
off size the content and we're gonna make
our textbox bigger. So now it's actually bigger
than our texts needs. So if I select my
text here, currently, it's set to just take
up as much space vertically and
horizontally as it can. So what we can do is if I wanted to my text
to be centered, we could set it to
a center alignment, and now it's centered in the
middle of our vertical box. If I resize my box, you can see that it
changes its center. Or we can select our text again and set it to be right aligned. And that will mean that the
text is now attached to the right side of
our vertical box. Next, we also have the
vertical alignment, and this allows us to control the vertical position
of our text. Now currently it's set
to fill vertically, but we also have its
size set to auto. So the text is just going to use as much space as it
needs vertically. But say I wanted
my text to be more in the center of
our vertical box. What we can do is we can
tell our size to be filled. And this means that our
text is basically telling the vertical box it wants to
use as much space as it can. Then we can use our
vertical alignment. We could set this to say center, and that will be centered in the space that it has available. Now, these settings can be a little bit confusing
to begin with, and a lot of the time
you just have to play about with them to get the result that you're looking for. But they can be
really helpful when working in things
like vertical boxes. And the behavior of these
settings are going to depend on the widget
that you have selected. So if we have to
grab a button and drop this inside of
vertical box here, you can see that it's
actually extending itself to the full size it
has available in the width. And the reason for that is
because of our alignments. Now, if I was to set my
horizontal alignment to center, you'll see my button
actually gets much smaller. And that's because
if we go to Style in the normal drop-down here, our image size is
set to 32 by 32. So if I was to increase this, you can see my button
actually gets larger. Or if I was to increase
it in the X value, you can see it gets longer. And if I was to set my
size up here to fill, you see my button
gets much bigger. Now it's not taking up all of
the available space because our text up here is
also set to fill. So if I was to set this to auto and see that now my box
is pushing all this texts out of its way
and it's taking up as much space as
it can vertically. And that's because our
vertical is set to fill vertically for us to take
on fill horizontally, you'll see now a button
takes up all of this space. And just as a side note, if you're changing the size of a button in its normal style, you'll probably want to do
the same for both hovered and pressed because you've
got to remember that when you hover
over a button, it will then start
using these settings. And if your size is different
from your normal size, then your button
is going to shrink down whenever you hover over it. Don't worry too much if those settings have
gone over your head, the best way to learn widgets
is to just play with them, try and make little things and get them working
and laid out the way that you want to by
using these buttons here. And also the padding
and alignment settings that you
have available by selecting the individual widget. Now we've been using
the vertical panel, but there is also a
horizontal panels. So if we go to our
panels option, you can see we've got
the horizontal box. And if we drag this in,
this behaves pretty much exactly the same
as our vertical box, but instead it's horizontal. So if I grab, say, a text widget, we just drag
that into our horizontal box. You can see that it's added it inside our horizontal
box down here. If I was to add another
one to our horizontal box, you can see that it's added it, but now it's moving them horizontally instead
of vertically. Now, the cool thing
about these panels is we can use them together. So if we zoom out
a little bit here, I'm going to delete all of
these in my vertical box. And we're going to add a horizontal box inside
the vertical box. So we'll go down two panels, find a horizontal box. And we're going to
put this inside our vertical box like that. Now, inside our
horizontal box we can add something like texts,
will add some texts. And maybe I want
an image as well. So if we imagine this was
maybe a list of items, we'd want the items Image and then some texts
for its name. So we'll add an image as well to our horizontal box like that. Now, we can change the
order that these are in, inside our horizontal box. We can select them
and you can use these little arrows just
to move them about. Or in the hierarchy panel,
we can just drag it. And we get this little
blue line that tells us if we're moving it so we
can move it above our text. And now it's above
our text or in front of our texts for
the horizontal box. Now say I didn't really
like the way this looks. I wanted some space
or maybe I wanted my textbox to the other
side of our panel here. I select my text. We could set it to
fill and I'm going to set it to right
align horizontally. And now my text is over here and my images are still on
the left-hand side. So now we could copy and
paste or horizontal box. So we'll select
it, do Control C, then we'll select
our vertical box and do Control V. And now we can paste in a couple
of our vertical boxes. You can see now
we've got a list of horizontal box inside
our vertical box. And then those horizontal box have our images and our texts. So we can select our
text and change these. We could change
this to say sword, this to gold, and this to
health drink, for example. Now we have a vertical list of horizontal boxes that then
have this information inside. Now, maybe we wanted
to change the distance from the edge of
our horizontal box to the edge of the vertical box. We can do that
using our padding. So we can set our
paddings, say ten. And that will actually
give us some space between our different entries and also the edges of our vertical box. So we could do this
with each one. We can set this to ten as well. And then the same with this, just to tidy up a
little bit like that. Now if we wanted to, we could
set an image for these. So if I select one
of the images here, we can set an image. Now I've only got the images
that come with the engine. So we'll, we'll
use, say this one. That's actually set our
image that we could sit and have 12 here
so we can scroll down, find a different image, maybe this Android icon, you can see. Now we can set images for
each one of our rows here. Another way we can use
padding is actually within, say, a vertical box here. Maybe I wanted my
text to be this side, but I wanted a bit of space between the image and the text. What we could do is
change this back to auto, so it's over this side. Then we could
either use padding. So I could open up padding at
a left padding of say, 50. And you see now our
text is 50 centimeters, so 50 pixels away
from our image. Or if we get rid
of this quickly, we can use a spacer widget. So if we search for space, we can use a spacer widget
and we can drop this in, in-between our image and
our texts in the hierarchy. Just it, select the spacer
and we'll set its size here. We want the x to
be the horizontal, so we were increases to say 100, and that gives us a 100 pixels between our image and our sword. Now, so far we've been
looking at panels and panels for the most part can
have unlimited children. So we can add as many
widgets as we want to our canvas panel or to our vertical box or
the horizontal box. But some widgets don't
have that freedom. If we get rid of our search
here and we add, say, a button, we can add
a child to a button. So if I grab, say, some texts, I can drag this on top
here to add it as a child or just drop it on the button
in the hierarchy panel. And you can see now we've got the text and that's a
child of our button. But if I was to grab,
say, some more texts, I can't actually add
that to our button anymore because our button
can only have one child. So a good way around this is if we remove the texts
from our button, we can use a panel like
our horizontal box. We can add that to our button. And now our horizontal box
as a child of the button. But we can add as
many children as we want to, the horizontal box. So we could grab,
say, some text, add that to our button, could also grab an image. So we can add that
to our button. Now, currently it's
leaking out of a button. But what we can do is
select the button, we can re-size it so our content
stays inside the button. Or if you remember, we can
click Size to content. Button will actually
just resize itself to whatever space it needs
for the content inside it. So this is a really easy way. You can make widgets that
can only have one child, have as many children
as you want just by using the panel boxes down here. Now one thing that can be
challenging with working with these panel boxes
is say I wanted my texts or this entry here in our vertical
box to be larger. There's no size option
that we can just control. But what we can
do is we can wrap individual elements
with a size box. So say, I wanted this image
to actually be much larger. What we could do is
select our image here. We could wrap it by
right-clicking, do rap with. And basically this just
means we're telling the image to be contained
in another widget. So we're going to select,
say, the size box. And now our image you can
see is inside a size box. That size box is still
inside our vertical box is just kind of put our image
in that size box for us. We can do this with
our boxes as well. So if I select my image
here, for example, we could wrap this with say, a vertical box if we wanted to. You can see we've
got vertical box or horizontal box or any of these options
that you have here. Heading back to our size
box that we just created. You can see that we've got
some size options here. So what we can do is we can select these options to
turn on the size overrides. If I enter a text here, so say 100 by 100. You can see that
it's now forcing this image to be that size. So this can be really helpful when working with vertical boxes because sometimes
you just want to force a widget to
be a certain size. And the controls here can be
a little bit restrictive. So using a size box, we can just force
a specific size. There are a few other
options here as well. So if we untick or
override options, and the reason why I'm
taking them is because these basically just force the
widget to be this size. None of these options will better if you've
got these tectonic. So we're just going to
take these off for now. We can also set a
Min and max size. And this basically tells us
that we want our widget to at least be say, 50 by 50. But it can resize itself
up to say, another site. So say 200 by 200. You see currently
it's 50 because our images only a small image. But if our image was larger, it would actually make use of that additional space
up to 200 pixels. And then the image wouldn't
get any larger than 200 because we say max size. Now at the moment
we've just been adding widgets manually by dragging men to our canvas panel or our vertical
box, for example. But in our next lesson, we're actually going
to be learning how we can create
widgets using code, add them to these boxes. We'll also be looking
at the scroll box, so I'll just bring that in here. And basically the way
the scroll box works is once the widgets inside it, the children inside it get
larger than its current size, will get a scroll bar up here, will actually be able
to scroll through the content inside
the scroll box.
41. Widgets (Creating Widgets): Hey everyone. In this lesson we're
gonna be learning how to create widgets using code, instead of having to
manually drag and drop these widgets
into our panel here. We're also going to be
looking at the scroll box. Now, I'd explain this a little
bit in our last lesson. But essentially,
when the content of our scroll box gets larger
than the box actually is, it will give us a little
scroll bar that we can use to scroll through its content. So to get started, what we're gonna do is we're
going to create a data table which is going to contain some information
about some items. And then we're gonna
have our widget code create a listing for
each one of those items, and we're going to store them
inside our scroll box here. So to start with,
we're gonna go to the Content Browser and we're going to create a new widget. And this is gonna
be a custom widget that we're actually
going to spawn in and used to display
our items of information. So we'll right-click, go to the user interface option
and create a new widget. We're going to
select user widget. And we're going to
call this BP on score item listing like that. And we'll double-click
it to open up. And I'm just going to drag mine up to the top here like that. Now the difference with creating this widget compared to our HUD, which is we're not
actually going to use a canvas panel because our item listing widget is going to be added
to another panel. Similarly to how we've done
our images and our texts, the item listing isn't going to take up our entire
players screen. So we're not going to
use a canvas panel, we're actually just going to use directly a horizontal
box to start with. So I'm just going to
grab a horizontal box, put that here. That's going to allow us
to lay out with things in a horizontal direction. We can you grab a image so
we'll find the image option. Well, I will add some texts for the
player or the item name, and I'll also add another text. Maybe we will have a cost value. Right now this looks a bit strange because if you remember, we're still previewing this
is if the widgets being added to a 120th
by ten ATP screen. But what we can do to give us
a bit of a preview is to go to the screen size or the
full screen here to custom. And this allows us to
actually just manually enter in a pixel size for our widget. Now remember, this is
just for previewing. This isn't actually the
size of our widget. So this just gives us an
idea of what the widget will look like at a certain size. I'm going to set
mine to say 350. And the length, or maybe we'll make it 400 and the length, maybe AT, and the width. So now we get a little bit better idea of what our widgets actually going to look like once we add it to a scroll box, like we did in the layout video, you can spend a little bit
of time moving these around, adding spaces,
changing the fonts or colors if you want to. I'm going to put my cost
so it's against this side, so I'm going to
set it to align to the right side and we're
going to take on film. So now our text is on
this side of our widget. Now, we're also going
to need to change these widgets values in code. So what we're gonna do
is we're going to select each one of our widgets here and we're going
to rename them. So I'm going to rename
image to Item icon. And we've got is
variable turned on, which is good because
we will need to access our image in the Event Graph. Now if we select our textbook, you can see it doesn't
actually have that TikTok. So we're going to take that on. And I'm going to set
this one to item name. And this one will
take this on as well, and we'll call this item cost. So now if we head over to
our graph view and compile, you'll see that we've
now got variables for each one of our widget types. Using these, we can
actually just get them as variables and we can set
information about them. So if I wanted to change
our item cost text, I can do set text. We can use the set text node, and this actually allows me to change the text that's being displayed by our item cost text. Now we'll just delete
these nodes because we actually need to set
up our data table. So we'll save our
item listing for now and go back to
the content browser. Before we create a data table, we need to create a struct first for that data table to use. So we'll right-click
and we'll go to blueprints Then structure. And I'm just going to call
mine S underscore item. And we'll open that up. And in here we're going to
add some new variables. So I'll add a new variable. The first one, we'll call name. We'll change this
to be a text value. So this will be the
name of our item. We could set a cost, so we'll call this cost, and we'll set this
to an integer. And we could add another value, say for a texture, will search for 2D texture. And we want the 2D texture
here, object reference. I'm just going to
call this one icon like that. And we'll save this. Now we're going to head back to our content browser and
we're going to create a new data table using our S
underscore item structure. So we'll right-click, go to the miscellaneous option
here, select data table, and then we're going
to select our S item in the drop-down
here and hit Okay, then we'll call our data
table item list like that. So now we need to open up the item list and actually
add some items to it. So we'll open that up. And we'll add some new rows. So I'll add a new row. I'll call this say sword. Sword, sword. And we'll set the name to sort. We'll set the cost to say five. Now I don't have any
icons for items, but we can use some
just random textures. So maybe I'll pick the
camera texture for this one. Well, I didn't have a
row. We'll call this say spelled that wrong again. So this is the ACS. Then we'll set the name for
our AKS row two acts as well. We'll set the cost of say, 20 will set another texture. So I'll just pick
this green face. We'll add another one, and
I'll set this to be hello, drink. I spelled
that wrong again. Drink like that. And again, we'll set
the name to help drink, set the price to say,
or the cost to two. And we'll pick another image. So I'll pick, say, the Android icon here.
That will do for now. We will add some more so we can get our scroll box working
a little bit later on. But for now that'll do that. We'll head back to our
item listing widget. Now we need to create a function that's
actually going to set up this listing and set our item cost icon and
names for this widget. So to do that, I'm going
to create a new function. I'm just going to call
this setup listing. We're going to add an input, so we'll select the
input node here. And under inputs we'll
add a new input. And I'm going to set this
to F underscore item. Now, that's the struct that
we used for our data table. If you remember, we
will be able to input a item struct to this function. So we'll set it to that and
we'll set the name to item. Now, we're going to use
the information from this struct input to
actually set our widgets. If we drag out, we can break our item struct and we can
access the name cost an icon. So to start with, we'll
grab the item name Widget, Get that variable, and then
drag out and do set text. And we'll do the setText node. Connect that up to our input. And we're going to
take the name and plug that into the text. Then we'll get the item cost. Do the same thing. So set text, get that node. Connect that up to
our previous setText, and we grab the cost. We can plug that straight
into our texts as well. It'll give us this node
that just converts an integer into text. And then lastly, we're
going to set the icon. So we'll grab item
icon and we're going to drag out from
this and do set brush. We want set brush from
texture like that. And this allows us
to basically just tell what our image widget, which texture you wanted to use. So I'm just going to
grab our icon here, connect up to texture. So now when we run
this function, we'll set the item name cost and the icon or to wherever struct
we provide to the input. So now we can compile and save this and we'll
head back to our HUD. Now, I've got the scroll box
from our previous lessons. So I'm actually going to
make this a little bit larger because it's quite
small at the moment. So it's just a bit bigger there. And we're also going to add a vertical box to
our scroll box. Now, we could just add our widgets directly
to the scroll box. But the problem with
that is you might get some scaling issues and there's also some options
that will be missing. So if we scroll down, I'm going to grab a vertical box and add that to the
scroll box here. Now, if I was to
just, for example, say grab a button and add
it to the scroll box. If I select that button, you can see that we're
actually missing those fill and auto options. Whereas if I add that
to the vertical box, you can see that we get
those options back. So that's why I'm
actually going to be adding, we can
delete this button. Now. I'm actually going to
be adding our widgets to the vertical box instead of
directly into the scroll box. But don't worry, the scroll
box will still behave how it should once our
vertical box inside the scroll box gets too
large for the scroll box will get a little scroll bar and we'll be able to scroll
through the content. For now, we need to be able to access this vertical
box in our code. So we're going to do like we did before in the item listing, we're going to select
the vertical box that we've added
to the scroll box. And we're going to say
his name to item list. And we need to take on is variable and then we'll compile. Then we're going to head
over to the graph mode and we're going to use
the construct node now, yours might be grayed out. Mine isn't because I
moved it earlier on, but I said it's grayed out. That's fine. You can still drag out from it and it works fine. So what we'll do is
first we need to get all of the entries from
our item list. So we're going to right-click
and do get data table. And we want get data
table row names. And this allows us to set
a data table and it will give us all of the row
names from our item list. So it will give us all
of these names here. So next we'll head
back to the hood and we're going to set our
data table to Item List, will connect this up to
our Event Construct. Then from the outro names,
we're gonna do a loop. So I'll drag out and
search for loop. Now, I actually had
a bug while filming this lesson where my loop
nodes one coming up. So if you do have that issue
where these aren't here, you can go to the
Content Browser, find the engine folder. If it's not there, you can
show it by going to settings. Click on Show engine content, then go to engine,
search for standard. And you want standard
macros, just open that up. And then if you go back over to the widget to
your Hudson Bay, drag out, you should
be able to find them. Hopefully you don't
get this bug, but just in case you do, that's how I fixed it. So just do that. Now, hopefully you have
these loop node showing up. So I'm just going to
search for loop and we want to do a foreach loop. And that's going to
loop through all of the different entries
from our data table. And using the row name, we're going to get the data or get the struct from
our item list. So we're gonna do
get data table. We won't get data table row. We'll set the data
table to the item list. And you can see that
we've got our role name. So we're just going
to plug that into array element because
if you remember, this is providing us with
all of the row names. So each time this runs, it will give us one of the
row names from our item list. We'll connect this
up to the loop body. Then we're going to create
our item listing widget. So we'll do create widget. We're going to set the class to our item listing Owning Player. We can just drag out and do get Owning Player because
we're inside a widget, we can just supply
our new widget. We have our current
widgets Owning Player. Then we'll connect up row
found to create widget node. Then from return value, we want to set up this
new item listing widget. To do that, we're going to use that setup function
we just created. So such was set up. And we want the setup listing function then which
can grab the row or the outro from our item list and connect
that up to set up listing. Then lastly, we need
to actually add on new widget that we've created
here to our item list. So I'm going to
grab the item list. And we're going to drag out
from that and do Add child. We want our child to
vertical box will connect this up to our
setup listing here. And then for content we need the widget that we're
adding to the item list. So we'll just grab
the return value and connect up to
content like that. So now just to summarize the
code we've just written, what happens when the
widget is created is it gets all of the row names
from our item list. So I'll get these three
rows from our item list. Then it will loop through
each one of them. So this code here that we've
got highlighted 13 times. And each time it runs, it will run with a different
row name from our item list. That means we will
get the different struct information
from our item list. And that sets up or creates a new listing
widget and gives it a different information for each widget listing we create. And then for each
one, we add them to the item list widget that we added to our scroll
box and here. So now we can actually
test this out in game. I'm just going to delete
these old widgets so we added in our
previous lesson. So I'll just select
the vertical box here, delete that, delete the button. We'll select this
horizontal box here. Delete that and we'll delete
this text box just so we can see our scroll
box a bit easier. I'm going to move the scroll box just up to the
top left-hand corner there. So it will compile that. And now we're actually ready to test this, so we'll hit Play. And now you can
see we've actually got all of the items that we added to our item
list into our screen. And that's all being
done via code. Now currently we don't have the little scroll bar because
there's only three entries, so it doesn't take
up enough space to actually cause the
scroll bar to exist. But what we can do is if we
exit out of plane editor, we can just go to the Item List. You could add individual
items if you wanted to. But I'm just going to take
say the ax here and we'll duplicate that a
few times and then do the same with
the health drink, which is duplicate
that a few times. Now when we hit play, hopefully we do have that scroll bar. Now currently I can't actually interact
with the scroll bar. And that's because our mouse is locked to our players camera. So next I will just
show you how we can set up a little bit of
code that allows us to release our mouse from
the camera control so we can actually interact with
our different UI elements. So to start with, we'll go
to our character blueprint. So I'll just go to, we'll get rid of this search, will go to the content folder for the person, then blueprints. And we'll go to the ThirdPersonCharacter
and open that up. Now we've still got some
code from previous lessons. Obviously we've got the
code here that which actually creates our HUD and
adds that to the screen. So we do want to keep that. And we can delete this kill player code because
I'm not using that anymore. So what we're going to
do is add an input, so I'll right-click and
search for input event. I would do a shift.
You left shift. So every time we press Left
Shift will toggle between controlling our characters
camera and then having our mouse actually
free to interact with UI. So to start with first, we
need to get wherever on our mouse is currently
controlling the camera or not. So we'll do get
player controller. From that, we'll drag out and
do get Show mouse cursor. This will be true or
false whether or not the mouse cursor is
currently visible. So we'll do an F. That'll
allow us to control which code we run if the mouse cursor is currently visible than
we want to hide it. So we'll do or will copy, I'll get player controller. We'll drag out from that
and do set input mode. And we want to set
the input mode to game only because
we're switching. If the mouse cursor
is currently visible, we're switching to gain mode, so we just want to
control our camera. So we'll connect up to true. And then we also want to
hide our mouse cursor. So we'll drag out and
do show mouse cursor. And we want this to
be false like that. Then if our mouse
cursor isn't currently visible than we want
to set its visible. But first we want to set
it to gain mode and UI. So we'll do set input mode, game and knew why the reason
we're using game and UI and not just UI is if we were
to set it to just UI, none of our inputs and our
character would work anymore. So if we were to press
left shift again, we wouldn't actually
be able to exit the Y mode because this
node wouldn't run. So instead we use the set
input mode, game and gy. And we'll connect
this up to false. And then we're going
to get our variable that we actually created
in a previous lesson. You can see that
the code down here, this is just where
we create the HUD. We set it to a variable and
then add it to our viewport. So we're going to
use that variable to set the widget and
focus like that. Then lastly, we want
to show our cursor. So I'll just drag out from
get player controller again to set show mouse cursor. We want to take that on and connect that up to
our output here. So now this is all set
up when we press Shift, it will release our mouse from camera control and
allow us to control the UI. And then when we press it again, it will take back control
of our players camera. So we can compile this
and test this out. We'll hit play. So currently
I'm controlling my camera. If I hit Shift, you can
see I've now got my mouse. I'm no longer
controlling the camera. I can actually use our little scroll
bar here as well to scroll through all
different entries. Now, in this lesson,
all we've done is used the horizontal box to
add to our scroll box. But if we wanted to,
we could edit the item listing widget as much
as you want it to. So we could go to the designer. Maybe I wanted this to
actually be a button. What we can do is right-click
the horizontal Boxer. We could do rap with
and we select a button. Then we could have
it so that when this button is pressed,
it run some code. So we can select
the button here, scroll down to the
bottom, and do unclicked. That creates us a new event. So whenever this listings button gets pressed, it
will print out a. We could do a print string, and we can have this
print string print out the current value
of the item name so we could get
itemName, do get text. We would use the getText. Note it. So now whenever we
click this button, the name of the item that we've clicked
on will be printed. So we'll head to
the game, hit Play. And now you can see
these are buttons. So currently I've got
control of my camera. If I press Shift, got my mouse now, now when I click these, you can see it's
actually printing out the name of the item. So that's it for this lesson. Hopefully you now understand
how you can actually create widgets and then add
those widgets using code.
42. Widgets (Bindings): Hey everyone. In this lesson we're
gonna be taking a look at widget bindings now, which it bindings
allow us to control certain properties
of our widgets using variables or functions. So to give you an example, if I drag in an image here and I'll just make
it a little bit bigger. If you look over in the right-hand side
of the Details panel, you will see this
bind option for a few of the different
properties that our image has. Now, these are actually
settings that we can control with either a variable
or a function. So a good example of this is
the visibility option here. Now, this basically
just sets whether or not the widget is
visible or not. So if we leave it as vegetable, we can pause it and hit play. We'll see we've got
our image here. And if we go back to the hood
and I set the visibility to hidden compile and
then we hit Play. You can see it's
no longer visible. But we can also control that
setting with a variable. So if we go back to our HUD, select our image here, you can see we have a bind
option next to the visibility. And right now we only have
the Create Binding option, and I will explain
that in a minute. But if we go to our graph view here and we create
a new variable, and this is just
gonna be called, we'll call it image visibility. And we're going to set
its type to state, sorry, slate visibility. So we want Eastlake visibility. This is the type of
variable that we need to use when we're binding
to a visibility setting. So I'll do as component. And if you see down here, the default value is actually the same
settings that we have in our design view if I click the drop-down for
visibility here. Now that we've created
that variable, we can actually bind it to
this image is visibility. So we can hit bind
and you see that we can now see that
variable here. If I select that now, our image is now using that variable setting to
determine whether it's visible. And you can see this has
actually grayed out. Now, if we go to the Event Graph and select that
variable we created, It's currently set to Visible. So if we hit Play, you'll see it's visible. And if we go back and we set that variable now
to hidden in C, that is now hidden. And that allows us to control that images visibility
just using that variable. And we can change that variable, have we like, so for example, we could set it, we could set it to say, hidden after certain
amount of time. So we could add,
say a delay here. After two seconds, I'm going
to set our image to hidden. And we're going to
set the default to visibility so it's
visible at the start. Then after two seconds
there'll be set to hidden. If we hit Play, you'll
see it's visible now, and after two seconds
it goes hidden. Now we can also control other properties of our
widgets using variables. So if we head back to our HUD, go to the Design View and
we have our image selected. You can see that
we can also bind a variable to the brush. So we can use a variable to control all of these
settings here. So if we go to the graph and
I create a new variable, I'm going to call my
brush settings like that. We're going to change
the type to slate brush. And we're going to pick
the top option here. And if we compile,
you'll see that these options here
actually match what we have in the design of view
for our image brush settings. And if we click the bind, we can also set that brush settings
variable here as well. So now we can control our images brush settings using that
variable we just created. So if we select Brush Settings and then here we can
pick on new image. For example, I'm going
to pick this green face. And if we compile and hit Play, you'll see that we're now
using that green face. And it was still disappear
off to two seconds. Because if you remember, we have our visibility variable here, and that's what controls
our images visibility. So you can have multiple binds for the
different settings in here, for the same widget as well. Now so far we've just been using variables to control
these binds, but you can actually
use functions as well. So if we go to say the
visibility option here, if we just click the bind and if you ever want
to remove a bind, you can just click this
and do remove binding, and that will reset it back
to using this setting here. So now it's just set to hidden. So if I was to hit Play, you'll see it's just hidden. And even after two seconds it
won't change because we're now using this visibility
setting here again, and not the variable. But we can also use functions. So if we click the option here
and click Create Binding, this will actually create
a new function and we're still inside our
bp HUD here you can see the return value will be whatever the
binding requires. Because we're using
the visibility option. It gives us a visibility
output of our node. If I was to create one for
our brush, for example, if I remove this binding, then create a new binding. You will see that now
the return value is a slight brush value
because that's the variable it
requires for this bind. But for now, I'm just
going to set that back to our brush setting variable here. So it will use that variable that we created
earlier again over here and heading back
to our new function. So if we go to functions, you'll see we've now got
a get visibility option. And this is the function that we created when we created
this binding here. Now we can add code
here like normal to control what the
visibility is going to be. So for example, we could
do get player controller. From that we could do get mouse, will get, Show, mouse cursor. And we could drag out from our return value,
you get slapped. Plug. Show mouse cursor
into the indexer. So if the show mouse
cursor is true, then I'm going to set
our image to visible. And if it's false, then we're
going to set it to hidden. If you remember in
our previous lesson in the ThirdPersonCharacter, we set up this code here, which basically
allows us to toggle controlling the camera or
controlling the mouse. So now when we hit
play, you can see, I can't see the immature at all, but I'm taking
control of my camera. But if I hit Shift,
you can see now I've got my mouse and my
image is actually shown. And if I hit Shift again, you can see that
it's now hidden. And the reason it's doing
that, it's because in our HUD, this function is being run to determine our images visibility. That's saying if
the mouse cursor is visible or if this
variable is true, then we set it to visible. And if it's false, it
sets it to hidden. Now there's one other
example I wanted to give you and that's
using the progress bar. Now progress bars are typically used for things like
health bars and hunger bars or loading
screen and bars. So what we'll do is
we'll head over to the design view and we'll get the progress bar
from the pallet. Drag that in. I'm going to make mine a little bit
longer like that. Now we have a few
settings for things like the style which
control how it looks. But we're just going to focus
on the percent value here. And if this is 0, it means the progress
bar is empty. And if it's one, you can see as I move it up, it's now full. So our percent is always
going to be a value between 01 and that determines how full the progress
bar actually is. Now we can also use a
bind for this property. So you can see we have
the bind option here, so we can either
set a variable or function to control this value. Now, currently at
the time of filming, there actually is a bug in
the engine where you can't bind this to a variable
and give you an example. Normally you'd be able to bind this value to a float variable. So if I go and I create a
new float variable in C, you say amount and set
it to a float like that. And we'll just compile.
If I go back to the design view and I click
the bind option here, you can see that our flow is
not here and it should be. If your variable is
here, then that's great. You're using a newer
engine version and the bug has been fixed, so you don't need to
worry about this. But if you don't have it here and it hasn't
been fixed yet, there is another way we
can get around this, and that's just
using the function. So instead of just
selecting the variable, we can just do create binding. And in here you can see that
the return value is a float. And we can just take
our amount variable, plug that into the return value. And now we can use this
float to control the amount. So I can set it to say 0.2. We can hit Compile
and then hit Play. You can see that it's now
at 0.2 on the progress bar. Now we can actually set
up another widget that controls the amount
variable we just created, and that will actually update
our progress bar here. So if we exit out of
play, go to the HUD. We can add in, say
a slider here. And we'll make this
a little bit bigger. I'm going to change
this anchor point to the top right because that's
the point that's closest to. So I'll change the
anchor to that. And we can change the style just to be a little bit larger. So I'll make the ball thickness say for just so it's a bit
easier to see in game. Then we'll compile. And down here you can see we've
got an own value changed. And if we click the Plus button, that will create us an
event that allows us to set a variable using whatever the slide is currently
set to being just grab our amount variable
here, connect this up. And now when we
move our slider in game, you can see
it's over here. If I hit Shift to enter the mouse mode here you can see our image
is still showing up. We can't drag a slider
and you can see that our progress bar is actually
updating with our slider. That's pretty much it
for how you can bind variables and functions
to widget properties. If we head back to
the heart here, I'm just going to exit
out of planets to go to the Graph view if you ever want to find any of
the bind function. So we've created, when we've clicked the bind option
and done create binding, you can find those under
the functions tab. Just like any normal function. The engine just
automatically gives these names so you can
rename them if you want. And you can also
delete them if you're not using them, just be careful. If you delete one that you are
using in a widget binding, it will give you an error, so just be careful with that. That's it for this lesson. Hopefully you now
understand a little bit more about how bindings and widgets work and how you can use them in your
future projects.
43. Widgets (Borders, Overlays and Grids): Hey everyone. In this lesson we're
gonna be taking a look at a few
more widget types. We're going to take a look
at the border overlay and uniform grid panel. But before we get started, we're just going to
clean up our project a little bit from our last lesson. So I'm just going to select
these three widgets here, delete those, head over
to the Event Graph. I'm going to take
my construct node, connect that up to
this node here. Then we'll delete these
nodes that we're not using will also
delete this slider. And if we compile, it
should all be okay. Now heading back to
the design of view, first thing we're
gonna look at is the uniform grid panel. If we drag that in. And I'm just going to make
mine a little bit bigger here. This panel works similarly
to the horizontal box. The vertical box. The only
difference is it can have both vertical and
horizontal children. So to give you a quick example, if I just grab, say, an image here and I add it
to the uniform grid panel. You can see it. It's in
the top left-hand corner. I'm going to add an
additional image here. You see that it's still, both are still in this
top left hand corner. But you say if I
select one of them, I actually get these
arrows and I can position them in
different locations, either down or
horizontally like that. Now we can also
control this over in the Details panel
here you can see that currently this widget Row is set to one and its
column is set to 0. But if I was to set the
column to say three, You can see that it then
moves it to the third column. Now unlike the horizontal
and vertical boxes, you can also change
the alignment. So up here in the Details panel, if we wanted to say B in the
bottom right hand corner, we could do that using
these align options. Now we can also add widgets to our uniform grid
panel using code. And this is where they
become really powerful because we can use
uniform grid panels for creating things like inventories or more
advanced lists. So to give you an example
of how you would do that, I'm going to create a new
widget that we can also use the border and overlay n. So we'll head over to
the Content Browser. I'm just going to
click the Add button, go to User Interface
than Widget Blueprint will select use a widget
and it will go down. And we went home and S2, BP and Scott grid slot. And we'll open that up. I'm just going to drag mine
up to the top here like that. So to get started,
we're going to add the border widget to the
hierarchy, just like that. With it selected, you can see the settings for our border
over in the Details panel. And here is where we can set things like if we wanted to use an image and this
will basically just turn our border into an image. We can also set the color. So for example, if I
wanted it to be gray, I could just turn the color here to a darker gray like that. And it also gives us
options for padding. So this will affect any children that we
add to this border. Now borders can only
have one child. There are quite helpful
to act as sort of backgrounds or containers
for other widgets. And one of those
widgets is the overlay. So if we grab the
overlay and add that to our border like that, now, if I wanted to
add another child to the border, I can't. So if I grab the
image, you can see it won't let me add
it to the border, but our overlay can have as
many children as we want. So we're going to add our image
to our overlay like that. Now, with the overlay selected, you can see that
it doesn't really have any of it's own settings. And that's because it doesn't
really do anything visual. All it does is allow us to
add multiple widgets to it. And those widgets will overlay each other
so they won't be moved in different a horizontal
or vertical direction. They were just all stack
on top of each other. So before we start
laying out this widget, we're going to change the
size of our preview here because currently
it's 1920 by 1080, which is far too big. So we're going to change
the full screen option here to desired like that. Now, what this does is it basically just
tells the widget to take up as much space as
the content inside it does. So right now it's
very small because our image only takes up a
very small amount of space. But if we select
our image widget and set the image
to something else. So I'm going to pick
this little green face. You can see that it gets
larger because our image is larger than we could increase
this size if we wanted to, say 128 by 128 like that. Now you may notice
if you zoom in that the top is closer to
the edge and the side. And that's because if we
go back to our border, the padding is set to 42. And if we click the Drop-down,
you can see that the left and right values
or four pixels. So it's four pixels from
the edge for our image. And then the top
and bottom is two. So if we wanted this to be all the same,
we could do that. So I'm going to set mine
to say ten like that. So we just have a ten pixel
gap between our border and that overlay widget that's
contained inside our border. So now we've got our
icon image here. We're going to add
some texts as well. So we'll grab some text and
add that to our overlay. See that it just overlays
on top of our image. Now, our text is quite
large at the moment, so I'm going to
select it and just changes font size down to say 16 or maybe 40. Like that. I'm going
to change the text to just say 99, for example. And we'll set it to align to
the top right-hand corner, so we'll use the right
line and then we'll do, actually we'll just
leave it as top line. So it's now in the
right-hand corner. Now, maybe we
wanted to add, say, a progress bar to our grid
slot. We can do that. So we'll grab our progress bar at that to the overlay as well. Now I want this in the
bottom center here. So I'm going to select
the center alignment and then the bottom
alignment, like that. Now we can change the size of our progress
bar using a size box. So if we right-click it
and we can do rap with, then do rap with size box. This is going to allow
us to actually define the exact size we want
our progress bar to beat. So we can change the
width and height, set the width to
something like 95, and the height to maybe ten. And now we've got a progress
bar added to our overlay. That's the exact sizes
that we want to use. Now, maybe I want to push it up a little bit from
the bottom here. We could use the
padding to do that. With our size box selected. We can click the padding drop-down and pad
it from the bombs, say, five pixels like that. So now we have our grid
slot widget all laid out using an overlay
just allows us to overlap all of these
different widgets in the same space while giving us control of the padding
and alignment settings. So now we'll compile and
we're going to actually add these grid slots to our uniform grid inside
our hood using code. So before we do that,
we're going to delete these images that we added
to the uniform grid. With our uniform grid, we're
actually going to select it. We're going to call this grid. Now. We need to
take on is variable so we can access this
grid in the code, will compile and head
over to the graph view. So to start with, we'll move this code up
and out of the way. And we're going to add
a sequence now just so we can have both
pieces of code one. So this will run
this code first and then we'll add the rest
of our code down here. So we'll start by dragging out and searching for for-loop. We want the for-loop
option down here. And this allows us
to basically just specify the start and end index, which controls how many times the loop body will actually run. So I'm going to
set my last index. Do you say nine? So this will now run ten times because 0 is one essentially. So for every time
this loop runs, we want to create any widget. So we'll drag out
from loop body and do Create Widget like that. Then, like before we need
to get an owning place. So I'll just drag out and
do get Owning Player. Now we'll just provide
the Owning Player of HUD. And then we need
to set the class, so we'll set this
to the grid slot. Then we need to
get our grid panel and we're going to add this
new widget to our grid panel. Now because children of
a uniform grid can have a row and a column
which defines how far, vertically and
horizontally there. We're going to need to do
some math to determine where our new grid slots
should be positioned. So it will drag out
from the grid panel. Would you add child
to uniform grid? And we'll connect this up
to the create widget there. Now the content is just gonna be the new widget we created, but we also have an n
row and then in column, now we want to water
me how this works. So what we're gonna do is
first store the index. So I'm just going
to drag out from the index value on our for-loop
and do promote variable. I'm just going to
keep it called index. And we'll connect this up
to our loop here like that. Now we also need
to know how many columns wide our grid
panel is going to be. So we're going to create
a new variable for that. I'm going to call mine
columns like that. And it's gonna be an integer. So just set it to integer,
then we'll compile. And then we need to
say default value. So I'm going to
set mine to three. So to begin with, our grid panel will be
three widgets wide. Now using our index
and column values, we can determine which row and column grid
slots should be in. It will grab our index
and we're going to divide this by our columns. So do divide, connect
on up to n row. And we want to divide this
by our columns like that. Now the reason this works is because when we divide
the index by the columns, if this index value is
below the column value. So if this is one or two, the return will always be 0 because two divided
by three is 0, because these are integers. So there are whole numbers
only until this index is free. This, the return value of
r divide node will be 0. So that means that our
widgets will stay in the 0 vertical height until
this index hits free. And then this node will
actually return one because three divided
by three is one. Then that will actually
move our widget now down into the
next vertical row. Then we have the columns. And this actually works
a similar sort of way. So we'll copy these two
variables and we'll drag out from my index and do
the percentage symbol. So that's the
percentage symbol, hip. Now, this is the mode. So what this does essentially is still divide these two
values by each other. But instead of giving
us the result, it gives us the remainder. So if we connect
this up to columns, if you imagine the index is
one and the columns is free. Well, if we were dividing
them, the result would be 0. But because we're
getting the remainder, the remainder will be one. If our index is two and
our columns is three, and our remainder will be two. And this is what
pushes our widget along the horizontal axis. Now we've actually
finished our setup for spawning our grids
and then adding them to the uniform grid
widget so we can compare it and actually see
how this looks in game. So we'll hit play. See that now we have our grid. You can see it's three web and then it's
adding ten widgets. So we have nine and then
ten on the bottom here. Now currently there a
little bit squished because our actual uniform grid is too small to fit all of
these widgets sense. So what we can do is
just go back to our HUD, go to the design of view, and with our uniform
grid selected, we can just take on
size to content in C, it's gotten really small because currently it doesn't
have any content. But when we compile,
we hit Play. You will see that now all of our widgets are
the correct size. If we wanted to, we could
go back to our HUD. We could change
the columns value nice and easily by just
changing the value, good to say five. And then when I
compile and hit Play, you'll see that
it's now five wide. Now perhaps you wanted a
little bit of space between your widgets that are inside the grid. We could
do that as well. So we can head back to the HUD. Then in the design of view, select the grid panel. And in here we can actually
set the slot padding. So we can set this to say five. And we will have five
pixels now between order to children of
the uniform grid. So we'll hit play again. You can see that now
we've got a nice gap between those widgets. If you remember, like our list, we can change these
to be buttons. Currently they're
just static images, but we can change them
to be buttons like we did with our vertical
list here as well. So if we head back
to our grid slot, we can wrap our overlay
here in a button, so we'll go wrap with du button. You can see that now we
have a button and because we're still using the
border as our background, you can see that
the button actually has that ten pixel gap. So if we wanted to
get rid of that, we can just select our button, do padding and set this to 0. And you see that now
our button is actually going right to the
edge of our border. But we've still got a bit of weird padding on the
sides of our widget. And that's because if we select a button here and
we scroll down, you'll find in the I believe
it's installed. Yeah. If we open up the style, you'll see we've got
normal padding and press padding now because
we've got 12 here. If we open this up, you'll see
on the left and the right, we've got 12 pattern and that's what's giving
us that big gap. If we want to change this
to be even on all sides, we can just change
this top number here, say five, and then we'll do the same thing with the
press padding as well. Change that to five and
then we'll compile. You'll see that now we've
got the correct amount of padding from each
edge of our widget. Now we've added a button
to our grid slot widget. We can have code run
when that button is pressed so we can scroll
down to the bottom here, we have our buttons selected. We can add a onclick
events, so we can add that. And when we collect it,
we can run some code. So I will just add a
print string here. Now, when we compile
this and hit Play, you will see that we've
got our grid slots that are highlighted
like a button does. And if I press them,
you can see that that print string is running. Now, our uniform grid panel can also work in a scroll box. If we exit out of planets to
hit head over to the hub, then if we select our grid
panel and right-click, do rap with and we want
the scroll box like that. Now, our scroll box, we actually want to set a size, because if we have up to size, content will actually
never bring up that little scroll
bar because it will just keep getting bigger. So we want to uncheck this
and we want to pick a size. So I'm going to make mine a
little bit wider like that, but I'm going to
make it shorter. So we get our scrollbar come up. Then we'll compile. And we just want to make
sure our grid panel is set to fill horizontally
and fill vertically. Then we'll hit play. We
should see that we've got our vertical
scroll box here. And we can, if I press shift, we can scroll through
our grid like that. Now, maybe you wanted to add a background to this scroll box. We can do that using borders. So if we exit out now
and go back to our HUD, we can select our scroll box
and wrap this with a border. So we'll do border. So now our scroll box is
contained inside the border. If we zoom in, you can
actually see it's got some of that weird
padding going on. So if we select our border
here and we find the padding, I'm just going to set
mine to actually will sell it to say ten. Now will give us a
nice big border. And then we'll change the color. So with our border selected, we can go down to
the brush settings. And again, you can set an
image here if you wanted to. I'm just going to
use the brush color. And we can set this to say
be this red color here. Now when we compile
and we hit Play, you'll see that now we've got that nice background
color that we selected and we can still scroll through our list just fine. So that's it for this lesson. Hopefully you now understand
a little bit more about all three of
these widget types.
44. Widgets (Drag & Drop): Hey everyone. In this lesson we're going
to be taking a look at drag and drop operations
using widgets. Now if you didn't follow
along in our previous lesson, we created this grid here. We have these different widgets and put it inside a Scroll box. I'd strongly recommend going and following that last lesson, because we're actually
going to be using these widgets for
our drag-and-drop. So just to get started, I'm actually going to make
this a little bit bigger, so we've got a bit more
space to work with. So we'll go over to the hood
and I'm just going to grab our scroll box or
actually sorry, our border here, which
is going to make this a bit larger like that. Then we're going to go
into the Graph view, and I'm going to add a
few more slots as well. So we'll set this to say 19. So we will have 20 slots
this time instead, we can test this out, hit Play. You can see that we've got
all of our slots here and our scroll bar is working
correctly as well. So now we can X out
of plane editor and we're going to go to
our grid slot widget, then head over to
the graph mode. Now over here in the functions, we actually have some functions
that we can override. And these are functions are
all widgets have built-in. As you can see,
there's a lot of them. We're not gonna go through
all of these because some of them are a
bit more advanced. But if you hover over them, you get a little tool
tip that says what these functions are
responsible for. And there's a few ones that are handy to get familiar with. So we've got things
like mouse button down. So this is going to
be run if you press the mouse button down
while your mouse is hovered over the
widget and game, we've got things like the
drag functions over here. We're gonna be using those today to create a
drag-and-drop system. There's also functions for on mouse enter and
or mouse leave. And that's, those are gonna
be run whenever our mouse hovers over our widget and then stops hovering
over our widget. But we're going to start
with the and drag detected. And this is going to
be the function that detects when we hold down our mouse while it's over this widget and we
start to move it. That's when it detects a drag and this
function will be wrong. So we're going to click on this to override that function. And in here we've got
some inputs and outputs. So just to quickly
cover these inputs, you've got my geometry and this basically gives you
information about your mouse position relative to the screen location
and things like that. You probably won't be
using this too often. But what you may be using a lot more often is the pointer event. This allows us to
get things like is mouse button
down for example. And we can use this now to
check which mouse button was actually pressed down
when the drug was detected, because we can actually
drag with both far left, right, and middle mouse buttons. So if we only wanted
this code to run for, say, the left mouse button, then we would want to check
is the clicks button, the left mouse button. And all I did was click the
little button there and then click left mouse button to set it to left mouse button. We can also use this
pointer event to get the name of the button
that was pressed down. So we could do get
affecting button. And from here we can
do gets display, and we can get the
key display name. And this will just tell
us which key exactly was pushed down when this
drug was detected. But for today, we're
just going to be using the mouse button down. So just highlight these
and delete these, and I'm gonna make
it so that this code will only run when we
left mouse button drag. So I'm going to add an if here, connect this up to our
beginning node here. And then we're going to connect the rest of the code
up to our true. So now we're ready
to actually use the Create drag drop
operation notes, we're going to
right-click and search for Create, Create, drag. And we want drag drop
operation like that. And we'll connect this up
to the true like that. Now, we can use an
existing widget, but I'm actually
going to create a new widget that's gonna be used to basically follow our
mouse when we drag and drop. So we're going to
create a new widget. So we'll compile and
save this for now. And we'll right-click
in the Content Browser, go to User Interface. Do Widget Blueprint. Use a widget and scroll down
and we'll name this BP. Move widget like that. And we'll open that, whichever. I'm just going to drag mine
up to the top here like that. Now, when we actually drag
from our grid slot widget, this is gonna be the widget
that will be created and follows our mouse as we
move the mouse around. So we're going to want,
say, an image for this. So we'll start with an overlay. So it will grab an overlay, put that here, then
I'll grab an image. The reason I'm starting
with an overlay is just so we can have
multiple widgets, like an image and some
text for example. So we'll grab some text as
well, which is zoom in here. Now I'm going to set my
preview size to just the desired so we can see exactly how big our
widget it's gonna be. I'm gonna change the
image to say 64 by 64. We'll set it to be, make
it this little red face. Instead, we'll change our
texts to be a bit smaller, so we'll do like 14. Now our image is
still quite a bit. There we go. We want to
change its size again. We change it to 64
by 64, like that, and we'll make our
texts a little bit smallest, still, like 12. And we'll set it to just be
writing on, for example. Now I want my text to
be in the right corner, so it will use right alignment. And that looks okay to me. Again, this is just
a quick example, just showing you
how we can set up a widget and then drag it. Now we'll head back
over to our grid slot. And in the on drag detected, we actually need to create that widget that
we've just made. And then we'll supply that
to our drag drop operation. So it will move these
along a little bit. And we'll drag out and
search for create widget. And we want to set the Owning
Player to the owning class. So we'll search
for owning Player, connect that up and
we'll set the class to the move widget
that we just created. Then next we'll take
our return value from our Create Widget
note and plug that into default drag visual. And we'll connect our Create drag drop operation
to the returned node. And we want to use
the return value to provide the operation
to the return. Note here. Now we do have some additional pins on our drag drop operation
note here we have a class. I'm not going to cover
that because that's mostly C plus plus stuff and you pretty much always be
using the default one anyway, you can add some tags. So like in our tags lesson, you could add a couple of
different tags to this. And then on the other end, when we actually
drop our widget on, say another widget will be
able to read those tags. And then we've got payload. Now payload can be
any object you want. It can be an actor or whatever. And that object can be used to store variables or functions. And again, we'll have
access to this on whatever widget we
drop operation on. So you could, if you
are passing information from this widget to the
widget that we drop it on. You could include some tags or even an object that just has a ton of information
that you can then read on that other widget. Now for now, we
won't be using these because they're a little
bit more advanced. But we also have a pivot option. Now this is basically just where the widget will be locked
when on our mouse. So if its center, it means that our mouse, if it stood still,
the widget will be around our mouse with
the mouse at the center. And as we drag it,
the mouse will always stay at the
center of our move, which as we move around. And there's a few
different options here that you can choose from. I'm just going to keep
mine health center center. And then you've got
some offsets so you can add some pixel offsets. So maybe you wanted the mouse to be at the center of
the move widget, but you wanted to add, say, a ten pixel offset to the left. You could do that
using these values. Now currently this
code won't ever run. And that's because we
actually need to tell the widget when there's
something being dragged. So to do that, we actually need to go to the
override and we need to go down to the
on mouse button down. Now, this will run whenever the mouse button is pressed
down on top of our widget. So to start with, we
first want to check which mouse button has
been pressed down. So we'll drag out from here
and do get affecting button. And from that we can actually
drag out and do the equals. And this allows us to check is this button equal to
the button we set here. So I'm just going to click
the little keyboard button here and then left mouse. So it sets it to
left mouse button. And we'll add an if node. So it will do if like that. Now we can have,
if you wanted to, if you add code that
you want it to run for when the left mouse button
clicks on our grid slot. And the different code that runs when we write mouse-click, you would want to
add this in here so we could copy and
paste this node, connect that up to
the effecting button, and then we can change
this to white mouse. So then we could
have another if, if the left mouse
button was pressed than the true pin here would run. And if the right
mouse button was pressed and the troop,
and here we're drunk. And then you could
have different code depending on which
one is pressed. Now because I only want my drag drop operation to run
when we left mouse button, we're gonna be adding
that code here. So we're going to drag out
from true and we're going to search for drag detect. We want to detect
drug if pressed, then we need the pointer events. So we're just going to
grab the mouse event and connect up to
the pointer of m. And then the drug key, which is going to click
the keyboard and then left-click to set it to left
mouse button like that. And this node is basically
just going to detect, is the mouse currently
dragging our widget. And if it is, we
want to pass that to the returned node and the
return value to return value. And this is actually what's
going to cause are on drag the text function
to run and then have all of the code that we
added in here run as well. So heading back to you
on mouse button down, we always want to have all
of the pins return a value here that's important for mouse handling and
things like that. So what we'll do
is we'll just copy a written note, paste
that down here. And maybe when we right-click on my mouse on the widget, sorry, we want something
else to happen, so I will just add say,
print string here. We can plug this into
the return value, and then it will copy this
and paste this down here. So if it's neither the left mouse button or
the right mouse button, maybe it's the middle
mouse button, for example. We just don't want
anything to happen. Now we don't want to
leave these return value pins empty like this. We need to either provide
a handled or unhandled. So if we drag out and
search for handled, now, if we return a handle that
basically tells the engine, Hey, we've handled
the mouse input. Don't let any other
widgets handle it. So don't run anymore events because the
mouse has been pressed. So we could use that for say, this code on our right
mouse button pressed, but maybe not for
the node down here. So we can drag out
and do unhandled. And that just tells
the engine, Hey, we haven't done anything
with the mouse input. If something else wants to
use that input than allow it. So we use unhandled here. So it should look like this. Now there's actually a change
we need to make designer. So if we head back
there, if you remember, we added a button that we're basically using as
a background that allowed us to press this widget. Now we need to
remove this button. And the reason for
that is the buttons overrides the code
that we've added here. So if we were to
be pressing down on this button or on
mouse button down, we'd actually not run because the button widget
handles that instead. So to remove that button, it's actually a really
easy way to do this. We can just right-click
on the button widget here and we can go
down to replace with, and there's an option
for replaced with child. And basically what that does is it just deletes the button and then we tell the
overlay to replace it. So we'll go to replace
with replaced with child. And you can see our button's
gone and we're back down to the overlay with all
of its widgets instead. Now if you want to, you can add some more padding
back to the overlay. So I'm just going to add say a five or ten actually, it
looks a little bit better. We've got a bit more padding now between the overlay
on the border. So now we can compile it and we can actually
test this out. We've just got a warning because I've deleted
that button. We can just go to the Event
Graph and you can see that we've still got an
event from that button, so we can just highlight
it, delete those, and we won't have
a warning anymore. So now we can actually go and play test this. So
we will hit Play. You can see that we've got our widgets are a
little bit squished because the scroll boxes a bit too small, but that's fine. We don't have to worry
about that at the moment. If we click and drag
on one of these, you can see that we actually
get our widget show up. And I've got control of
my camera at the moment. But if I hit Shift,
you can see I can drag and if I let
go, it disappears. Now, currently we're
not doing anything with this drag drop
operation information, but now we can actually drag off of any one of these widgets. And it gives us our little
move widget here as well. And if I try to drag from
my right mouse button, you can see we actually get
that hello texts print out. So it's printing out hello because we added
that hello print string to the press
button event. So now we've got dragging setup. We want to be able to pass information between
these different widgets. So what we'll do is we'll exhale planets and head back
to the grid slow hip. And we're going to
create a new variable, and we'll call this has item. And we're going to
leave it as a Boolean type and we'll compile. Then we're going to head to the designer and
we're going to set our little face icon here to be hidden if the boolean is false. So we'll go to the visibility down here,
we will use a binder. So we'll do create binding. And in here we're
going to return, if the item is false, we return that it's hidden. So we'll drag out
from the turn value. Do a select US has
item as the index. And if the item is false,
we wanna be hidden. If true, we want
it to be visible. So then we can compile that. Now, if we head back
to play the game, you can see that all of our little face icons
are actually missing now because all of them
by default have no item. Then we're going to head to our HUD and we're actually
going to change the code here so that the first slot always has its has
item set to true. So we'll drag out from
here and do an F. We want to check is
the index equal to 0. And we'll connect
up to condition. And if false, which
connect that up to here. And if true, we want to
get the return value from our Create Widget node. And we want to do set has item and we're going
to set it to true. Then we'll connect
the end up back to the Add child node like that. So all we're doing here
is we're checking, is this the first
index in the loop? If it is, then we set
it has item to true. And if we can pull
this and hit Play, you'll see that now
our first slot has a little face icon,
but the others don't. Now next we want to check before we do the drag operation, does the salt that
we're actually dragging from have the item. So we'll X out of hip, go back to our grid slot, and we'll go to the
on mouse to tap on, drag the texts, will
add a new check, will just move this
out of the way. We'll drag out and do if we want to check if
has item is true, then we will allow the dry
cooperation to be created. And if not, we
won't do anything. And we can quickly
test this as well. So we'll hit play and I'll hit
Shift to release my mouse. And you can see if I
drag from these sorts, it doesn't actually
create a dry cooperation. But if I drag from
this slop, it does. Next, we actually need
to store a reference to the original slot
that we dragged from. Because when we drop it on another slot that
doesn't have the item, we're going to
need to update the previous slot that did have the item to tell it no
longer has that item. So we need a reference
to this original slot. So to do that, we'll acts out of play and we're gonna go
over to the Move wager, then the event graph, and we're going to create a new variable. We'll call this old widget. And we'll set its type to be the grid slot widget
that we created. So that's the same one
we've been working in. And we'll set it to
an object reference. And we're going to take on
the little eye here just so it's instance editable
and we'll compile. Then we're gonna go
back to the grid slop. Here in the drag detects, we want to set that variable for the new move widget
that we've just created. So here we can drag out, we can do set old widget. We want to set this
old widget to be self because we're setting our
self to be the older widget. So we'll drag out from
that and do self. And we'll connect this up like that, and then
we'll compile. So now we need a function
that's going to run when we actually release or drag
on top of our grid slot. So we'll head over to the
override and we want to find the drop function here
and we'll create that. Now you can see we've got
those same inputs that we had for our previous functions, but we have a new one
now called operation. And this is basically
all of the information that we provided
from the on drag detect all of the
information that we provide here we can access
now in the on drop. So if I drag out and I
search for drag visual, you can see I can get a
reference to the drug visual, and this is a reference to the widget that we
have plugged in here. So using that, we can
actually drag out cost to the move widget because
ours is a move widget. If you remember when
we set it in the drug, this is the move widget. So we're going to cost to that. And using that cost, we can actually access the
old widget, gets old widget. And that gives us a reference to the widget that we
originally dragged from. Now we can also access the
tags and the payload so we can drag out from
operation and do get tags. And that gives us
the tags variable and also the platelets. If we do get payload, we can also add access that
object reference that we can provide over here in the Create drag drop
operation node. So now going back to the
On dropped function, we can delete these variables because we're not actually
going to use them. Then it's going to set
the old widgets has item. So it will search
for set has item. We need to set that
to false because it no longer has the item we need to set R has item
to true, so has item. We're going to set that
to true, like that. And we'll connect this up to
the return value will take on return value because
we've processed our code. So what we'll do, true, and we want to connect
this up to our cost here. Then we can compile this
and we can test this out. So if we go to the map, hit Play, I'm going to hit
Shift to release my mouse. If I start dragging,
you can see we've got our drag drop operation working. If I release it on another sock and see that that slots now visible and has its item set to true and the previous
one is set to false. We can do this with
any of our slots here, dragging this new operation
around to the other widgets. If I grab my widget and
I release it over here, say for example, over
on these other widgets, you can see nothing actually
happens because we haven't set up on drop functions
for these other widgets. So nothing's going to
happen when we actually release the dropped
operation on top of them. So that's pretty much
it for this lesson. Hopefully you now
understand how you can create drag drop
operations with widgets and also how you can transfer information from one widget to another using either the drag visual or the payload
object reference.
45. Animation Blueprints (Overview): Hey everyone. In this
section of the course, we're gonna be taking a look
at animation blueprints. Now, Animation Blueprint. So how we tell a Skeletal Mesh which animations we
want it to play? Now, a skeletal mesh is
usually a mesh that's been rigged to a skeleton in
a 3D modelling program. Then once in the engine, we can have that skeleton
play an animation and that in turn causes
the mesh to animate. Now in this lesson, I'm just
going to take you through a quick overview of the
Animation Blueprint editor, as well as the animation setup that comes with the
third person template. Now, before we get started, some of you may
have been following along in the previous lessons. All I've done here is created a new third-person template. So we've got a clean start for this section of the course. So to get started,
we're going to head over to the Animation Blueprint, which is inside the
character's folder, then mannequins, animations. You can see we've got a money and Quinn Animation Blueprint. So in this lesson
we're gonna be using the money Animation Blueprint. And the reason for that is
the Quinn animation blueprint actually uses the money one
as its parent blueprints. So all of the
functionality is actually inside our money
Animation Blueprint. So we'll open that up. And I'm just going
to drag mine up to the top bar here like that. Now you can see I'm currently
actually playing an editor, so I'm just going
to click the little stop button here to stop that. And now we've opened our
animation blueprint. You can see that we've
got the Event Graph. If yours isn't open,
you can always open it up here on
the tab at the top. Or you can double-click
the event graph here to open up our animation. Event graph is just the same as any other event graph you've
used and other blueprints. We have our code here
in our event graph. We've got our My Blueprint
panel where we can create and find our functions, variables, event
dispatchers, and macros. Now, the main purpose of
our Event Graph inside Art Animation Blueprint is to set variables that are then
used inside our Anim graph. So to open that, we'll head over to the My Blueprint
panel here and double-click and I'm graph and that will take us
to our Anim graph. Now, this has actually
changed quite a bit since the Unreal
Engine four version. So you may notice
some differences if you've used on ML
engine for before, but we'll start off
by just going to the locomotion
state machine here. So we'll double-click that. You can see that we
have a state and these are where we can set
animations to play. So we've got an
idle state and then we've got a walk
slash run state. If we open up our idle state, you can see we've got
an animation here using an animation sequence player That's actually outputting
an idle animation. We can see which animation
it's actually playing by the node name
at the top here. Or if we select it, we can go to sequence
and hover over the entry and you can see it
says MM, underscore idle. We can also click this
little browse to in Content Browser
button that will take us to the animation
that's being used there. We can see that this is the animation that's
actually being played whenever our characters
in this idle state. Now, heading back to
our locomotion machine, you can see we can click the locomotion up
here on the top bar. Now actually take us back there. We've also got a walk
slash run state. Now if we double-click
that to open it up, you can see that we've actually
got a different type of node that's being used
to play animation, sir. This is a blend space
node and it allows us to input a variable
like a float, for example, and have
different animations play depending on that
different flow value. So if we select this
node and head over to the sequence or the blend
space option, sorry, we can see that it's currently
set to BSIMM walk run, and this is the blend space for our walking and
running animations. We can go to that now by clicking the Browse
to Content button. That'll take us to
the blend space. And if we open that up here, now blend spaces allow us to add multiple animations together and have them smoothly transition between each other
using a variable. So you can see down
here we've got a speed value starting at 0. This is the animation that will play when our speed value is 0. And if I hold Control and
I start moving my mouse, you can see that
the preview speed actually increases and we start increasing our animations walk speed till we
get to this point. Now this point here is currently
set to the walk forward. So you can see when I move
the preview point here, our characters playing a
walk forward animation. As I keep increasing it, we start getting this
running animation. And as we get to the
end, you can see it's currently set to the run, and that's what we'll be played when we're out at the speed 500. So we can use this to
smoothly transition between walking and
running animations. When we head back to our
Animation Blueprint, controlling which animation
is being played in our side, our blend space using this ground speed
variable that's then plugged into this
blend space node. And depending on the
speed that we have, will output a
different animation to our output pose here. Heading back to our Anim graph. And I'm just going
to click on them. Grasp on the top bar here. Any animation that's
output from our locomotion is then input it into
this locomotion cash. Now this basically saves the current animation
that's being output by our locomotion, so we can use it later on. Now heading back into the
locomotion state machine, you can see that we've
got these arrows that go between our two states. Now these are transition
rules and these are how we check whether we should
be in the idle state. Or the walk slash run state. So if we hover over one,
you can see that we've got this variable that shows
up in the tool tip. And it's basically just
saying that this rule is set to the should
move variable. So if that variable is true, then we will transition from our idle state to
walk slash run. And then if I mouse over
the bottom one here, it's that same should move
variable but with a not. So if that variable is false, then we'll transition back from Walk slash run to the idol. And we can double-click these to actually look at the code. You can see that it's just a variable plugged
into the result. And then we can do the same
with the code for the role that goes from walk
to the idle state. So if we double-click that, you can see that we've got
that same variable with a knot node and then that's
plugged into the result. Now this should move
variable is set inside our event graph using some code and we will look into
that a little bit later. But if we head back
to the locomotion using these two states
and these two rules, we choose whether or not our
character should be playing an idle animation or a
walk or running animation. We then output that value from the locomotion state to
the locomotion cashier. So we can use that
animation later on. Now in our Anim graph here, if we go over to the
right-hand side, we've got this output pose node. Now, this is the animation that we will actually
see in the game. So whatever animation
connects up to here is what we will see when
we're playing our game. Now currently, these two
nodes up here aren't actually connected to any
of this chain down here. But if we open up our main
state state machine here, now our main states state
machine is exactly the same as our locomotion state machine.
They do the same thing. It's just that our main
states, state machine has different states insider. And if we take a look at
the locomotion state here, if we double-click that,
you can see that we're using a cash pose locomotion. Now this is the cash pose that
we set in our Anim graph. So if you look up here,
we're setting it here, and then we're using it in this locomotion state inside our main state state machine. So that's how these
nodes up here are actually connected out
to the rest of the code. Now, heading back into the
main state state machine, you can see that we've got
some states up here that aren't actually connected
to our state's down here. Now, the reason for that
is in Unreal Engine five, we have these new state aliases, nodes, and these allow
us to connect up states without actually having
rules connecting to them. Now we've got two
aliases in here. We've got the two falling
and the two land. Now you can tell
it's an alias by the little icon on the
left-hand side there. The way these work
is if I select the two falling
alias, for example, you can see over here on
the right-hand side panel, we've got the locomotion
on land states, tectonics. Now, you'll have a tick box for every state that exists
in your state machine. So we've got one for
locomotion, which is here, jump which is up here, full loop which is here, and then land which has here. Now if we had additional states, they would also be
listed as well. Now, because the
locomotion and the land of both text on this node will run all of the rules connected
to it while we're in the locomotion or
these land states. Which means that these two
rules here will be run every single frame if we
are currently playing the locomotion state
or the land state. And it's the same for
R2 land node here. This is also an alias
and you can see that it's got jump
for-loop ticked on, which means if we're
in the jump state or the for-loop state, then this rule will be
running every frame. And if at any point that rule becomes true while we're in
either one of these states. The two land will then
transition us from either one of these
states to our landscape. And that's how these states up here are connected to
the states down here. Now, just to cover the
rules that are going on in here while on
locomotion state is running and this will be
running whenever our character is idle or walking or running. And that's because
if you remember, we're using that
locomotion cache, which has being set by the
locomotion state machine. And that has our idle and our walk slash run
animations being sat there. So while that locomotion
state here is running, the two falling will
be running all of its connections to see if either one of these
rules are true. And if at any point
we start falling, is falling becomes true, we will transition from
locomotion to for-loop. And if we're falling and there's a velocity greater
than a 100 in the z. So if we're falling
past a certain speed, will actually use the
jump animation state instead of just going
to the for-loop. And then we actually
have a rule that goes between our jump
and our for-loop. And this just checks, is our jump animation
almost finished. And if it is, then
it will transition us from our jump
to our for-loop. And the reason it
does that is because we have this option
ticked on here, which basically just checks is the animation that
we're checking. Almost finished. If it is, then we
will transition to the state that
we're checking it for. Now, at any point
when we're playing or jump or a for loop
animation stays. This to land will
also be running. It'll be checking is,
is falling false? If it is, then that will
transition us from Eva, the for-loop, or jump to land, and then from land to
our locomotion again. So that's the basics of
how our main states, state machine actually works. If we head back to
our Anim graph now. Output wherever animation we're currently playing in
our state machine. So if we're just in
our locomotion state, this will output our
locomotion animation. If we were to say falling, it would play our for-loop. So that would be output
that would go into this, which is a montage slot. Now, we will have
a whole lesson on montages in the future. But this is just a slot that
allows us to play a montage. Montage allows us to overlay an animation on top of
our movement animations. But if no montage is
actually currently playing, all that will happen is
our movement animations will go into the montage slot. It checks if a
montage is playing. If not, then it just passes through and
no changes are made. Unless a montage is playing. Then that goes from our montage slot into
our control rig. Now, I'm not going
to be going too much into control rig in this course purely because it's a massive system on its own, which could have a
completely separate course, but we can see which
control rig is running. So we'll select the node. And in the Details
panel scroll down, you can see we've got
a control rig class. Here. It's set to the
mannequin basic foot IK. And we can find this by clicking the Browse to asset
and content browser. And we can open up
that control Rick, and you can see all of the code that's being run by
that control rig. Now again, I'm not going to be going through all of these nodes because control rig is a
pretty advanced system. But basically what this does is it does our foot
placement for us. I can give you a quick
example of what I mean. So we'll play an editor. And if I run over to this ramp and I put one on my feet up, you can see that the foot
actually increases its height because the height of the
ground is higher at that point. That's just a quick
overview of what control rig does in
this blueprint here. And all of this
code is happening inside this control
rig note here. So it takes in our
movement animations, it applies those
new foot positions for the height of the ground. And then it outputs that into our output posts here for our final animation
that we see in game. Now as we've been going
through the Anim graph it, you may have noticed
some variables like R is falling variable here, all of the ground speed inside
the walk slash run state. These are just normal
variables that were then setting inside
our event graph. So we can use them
in our Anim graph. So if we head over to
the Event Graph now just by clicking that in the
My Blueprint panel, as you can see,
we're saying some of those variables that we
use in the Anim graph. So we've got our
ground speed here, that's just getting the velocity from our movement component. Then we convert that into a float and set that
to the ground speed. We've got another variable
called should move, which determines
whether we should be an idol animation state or our walk slash
run animation state. And then we've got r is
falling variable down here, which just uses the
movement components is falling variable
that's built-in. And then we take that and set that to the is falling variable. And these are all set
by the event over here called event Blueprint
update animation. This will run every frame and update these variables
as they need to be. Then up here we've got the blueprint
initialize animation. Now this will be run similar
to a begin play notes. So this will run when the game starts or when our animation
blueprint is created. That just gets the owning actor, which is usually the
character blueprint. We cause to the character
blueprint character variable. And then we also get its character moving
component and set that as a variable
so we can use it down here to set
these variables. Now show you where
we actually set which Animation Blueprint
our characters using. We'll head over to the
ThirdPersonCharacter. So to do that, we'll go
to the Content Browser, then to third-person blueprints will open up the
ThirdPersonCharacter Blueprint. Then we can select
the mesh component over here in the
Components panel. And if we double-click it, it will take us to the viewport. Now overheat and
the Details panel. As long as animation mode is set to use animation blueprint, you should have this
Anime Class option. And you can see here
it's currently set to the eight BP Quinn
Animation Blueprint. So if you did want
to change that, you can just click the
drop-down here and find your new
Animation Blueprint. There are quite a few that
are built into the engine, but you won't typically
be using any of these. You'd use say for example, our money animation blueprint
or our Quinn one here. Then lastly, as a side note, maybe in the future you create an NPC character that doesn't
actually move anywhere, and you just want them to
play a single animation. You can do that by selecting the animation mode here
to use animation asset. And then you can set a single animation
that you want it to play without having to have
a whole animation blueprint. But for player characters, you'll pretty much always
going to want this to be set to use animation blueprint. And you wanna make sure
that the Anime Class is definitely set to your
animation blueprint. So for us, that's
the ABP Quinn here. So that's it for this lesson. Don't worry too much if you
don't understand everything. In our next lessons,
we're going to go into each system in a
lot more detail.
46. Animation Blueprints (Montages): Hey everyone. In this lesson
we're gonna be taking a look at animation montages. Animation montages, or how we tell our animation blueprint, the specific animation
we want it to play. So for example, if
your character were to reload or swing
a melee weapon, you would use animation montages to play those animations. Now in this lesson on some
of our future lessons, I'm going to be using
animations that aren't actually included in the
third person template. In the class description, I will put a link to
download the animations that I use in this lesson and
our future lessons as well. Once you've downloaded and
extracted those files, you should end up with a
folder that looks like this. Now we're going to add these
files to our projects. So we'll click in
the editor here, right-click our content folder and go to show in Explorer. This will show us
a content folder. And we want to move our lesson animations here to the content folder like that. Now you can see that
that's shown up inside our content browser. Now, if we open it, if the animations aren't
there, don't worry. All you need to do is close
and then reopen the project. So now I've restarted
my project. And you can see inside
the lesson animations, all of our animations are
showing up correctly now. Now we're only going
to be using one of these animations in this lesson. That's gonna be the
reload animation. So if in the lessons
Animations folder you search for reload, you'll see that we've
got a reload animation. Now we're going to use
this to create a montage. To do that, we'll right-click
and go up to Create, then select Create
and a montage. And we're just going
to keep the same name. So I'm just going
to press Enter. Now we have a new montage. Now if we open up our
animation montage, you can see that
actually looks pretty similar to an
animation sequence. I'm just going to drag mine
up the top here like that. Now the main difference is we
have this montage slot and a montage shot is how we tell the Animation Blueprint which
montage we want to play. So if we head over to our
money animation blueprint, if you remember
that's in characters, will get rid of this search, go-to mannequins animation
and open up a BP money. Then inside our Anim
graph, if you remember, we have this slot and it's
currently set to default slot. Now if we take a look back
at our reload montage, this is also set
to default swap. Now this means if we were
to play our reload montage, I Animation Blueprint
would be able to play it. Now currently our montage and our montage slot
inside our blueprint, or both using the same slope. But if we select the slot here
over in the Details panel, you can click the down
and see there's actually quite a few different sorts included with the
third person template. Now, if we were to
change this slot to use a different slot
and play, our montage. Montage would no longer
play because it would have a different slot
to the slot here. Now the main reason
that we can have multiple slots is
because you can actually have a character play more than one montage
at the same time. But each slot can only
play one montage. So that's why we can
have multiple slots and have montages assigned
to different slots. But for this lesson,
we're just going to be sticking with the default slots. So make sure you keep this slide set to the default option hip. And back in our montage
makes sure that the default slot and the
slot name is ticked on here. So now we're actually
going to write some code to play our montage. So we'll head over to
the Content Browser, go to the third person
blueprint folder, then open up the
ThirdPersonCharacter Blueprint. And in here we can add a
little bit of code that tells our character mesh to
actually play a montage. So we'll right-click. I'm going to search
for input event one, and we'll create
that input of them. Then we're going to grab
our mesh component here, drag out from that and
search for play montage. And that's going to create
us this new node here. Now I'll take you
through some of the inputs and
outputs on this node. Start with, we've
got montage to play. This is where we tell it which
montage we want to play. So we're going to select
our reload montage here. We've got the playwright. So if this is set to one, the animation will play
at its normal speed. But if we were to set to say to the animation would
play twice as fast. Next we've got start position
now this allows you to set the exact time that you want the montage to
start playing out. So for example, if you had a 10-second long montage and you wanted to
start at two seconds, then you would set the
starting position to two. Next, we've got the
starting section. Now I will explain this a
little bit later in the lesson. So we'll skip over this for now. Then for outputs we have the
normal execution output. This will just run as soon as the node has
finished running. Then we've got uncompleted. Now this will actually run
when the animation finishes. Then we've got on blend out. Now a cool thing about
montages is they blend in and out
when we play them. So you get a smooth
transition from the original animation you
were playing to the montage. And then when the montage
is almost finished, it will transition out back
to your original animation. And this blend out will run when the animation starts
transitioning out. Cover a little bit more about the transitions in a moment, but moving on, we've
got interrupted. And this will run if we cancel or stop our montage playing. And I will explain
how we can do that a little bit later
on in the lesson. Then lastly, we've got some notify execution
outputs and a notify name. I'm not going to be
covering notifies in this lesson because we will actually have an entire
lesson just for notifies. So we're going to
skip this for now. So now we'll finish setting up our code to actually
play your animation. I'm actually going to
create a new variable. We'll call this reloading. I'm just going to
use this so that if we spam the one input, it doesn't restart our
montage over and over again. So what we'll do is we'll
first check is reloading true. And if it's not true, then we'll set reloading
to true like that. And we'll connect this
up to the play montage. Then we want to set the
reloading to false. When IVR, it's finished playing the reload animation or it
gets interrupted like that. Now we're ready to
actually test this out, so we'll compile and hit Play. And now when I press one on my keyboard, nothing
actually happens. Now the reason for
that is when we imported in our
lesson animations, they actually came with
their own skeleton. Now, even though
both these skeletons are exactly the same, There's two skeleton
assets now in our project, one that our characters using, a one that our new
animations is using. If we exhale, have
plain editor and go to the lesson animations, open up mannequin,
then go to meshes. You'll see we've
got SK mannequin. Now this is the skeleton
or less than animation. So using, but if we go to
the Characters folder, then to mannequins meshes, you'll see we've got
another SK mannequin. Now this is the skeleton that are characters
meshes using. This is why our
animations on playing, but there's a new feature
and underwear on Jim five called
compatible skeletons. So if we go to the skeleton here inside our
characters folder, open that up, go to
the windows and we want to find the asset
details and take that on. Now here you can find
compatible skeletons. So we're going to
add a new entry. We're going to select
the drop-down here. We're going to find the skeleton that's in our lesson animation. So if you hover over, you can see it says
less than animations, slashed mannequins slash meshes. So we're going to
click on that one. Then we're going to save. Now all of the animations
that work for our lesson. Animation skeleton will
work with our character. So if we go back to the
level here, hit play. Now when I press one, you'll see our montages
playing just fine. If i spam one, you can see that it's actually
not going to play the a montage again until we finished playing the
original montage. And that's because
of the boolean that we set up to
stop that happening. Now one thing you might notice is while we're
playing the montage, or feet don't actually
move with our body. Everything is playing
that montage. Now, in our next lesson, we will look into blending
bones and that allows us to separate parts of the
body off from each other. So for example, while playing
our reload animation, we can have the legs. They'll be able to play
the movement animations and we will be covering
that in the next lesson. Now another thing
you might notice is if we go over
to the ramp here, you can see that my
legs up on the ramp. And if I press one,
you can see that the legs still stays
up and the ramp, even though that montage is
taking over the whole body. Now the reason this is happening
is because our montage here is played before the
control rig is applied. So the montage is played here. Then we apply the control rig, which deals with
the foot placement, and then we output
the final pose. So that's why our
movement animations are being taken over
by the montage, but the foot placement is not. So if I was to move my default
slot here for a moment, two, in front of my
control rig like this. And connect this all up. Now when I compile, hit Play, if I run over to the ramp, you can see that my foot
placement is still working, but if I press one,
you can see that it stops working while
I'm playing a montage. So it will just go back to
our Animation Blueprint and set this backup how it was. So it will just move
this forward over here, connect this up, and connect
our montage backup here. Like that. If you ever wanted to add a new montage
slot to your anim graph, you can just right-click search
for slot, scroll up here. You can use slot default
slot, then select it. And if you wanted to use
a different slot name, you can change that up here. But for now we can
just delete that node and compile our animation graph. Now, montages also
have other features. We can add multiple
animations to one montage. So over here, we've
got the asset browser. If you don't have yours that
you can always go up to Window and take on the
asset browser here. Now, using the asset
browser we can drag in animations to use
with our montage. So for example, we could use
the rifle are idle hip far. We'll just drag that. Now you can see we've got both
animations in our montage. Now currently these
are both set up to use the default section. So what will happen is
the rifle reload or play, and then our rifle idle
animation will play. But using sections, we
can actually divide up our montage into
different sections and play them differently. So to do this, we can
right-click on the bar at the top here and click
new montage selection. And we could call
this a loop section. Now we get this purple
line and we can actually choose where
this section begins. So if I put this say here, our section now for the loop section is
this whole area here. And then our default section
is this whole area here. Now currently all
that will happen is our default section will play and then our loop
section will play. But if we head over to the
montage sections here, you can see that we've
got some controls over how we can play these
different sections. Now again, if you don't
have this montage sections, you can go up to Windows
and tick that on here. Right now, you can see that it's currently playing
the default section. Then it will move on
to the next section, which is our loop section. I'm just going to make my window a little bit bigger here. Can you see the button is actually now in the right place. Now if we wanted
to, we could have these sections be
completely separate. If we click this arrow
here and do remove link, you can see that now these
are two separate sections, so only our default
section we'll play now. Because we've told it not to do anything after it's
finished playing. Now if we wanted it to play
our loop section again being click this little box
and do loop section. And now it's going to
play our loop section after the default
section is finished. Now we can also
make sections loop. So if we click this box next
to our loop section here, we can select loop
section again, and that will make
our loop section here just loop over
and over again. So once our default
finishes loop section, we'll play and this will just keep looping over
and over again. As you can see now. Now this can actually be
useful for different things. Say for example, you were making a reload animation
for a shotgun. Now, usually you can load individual bullets
into a shotgun. So maybe when you're
playing reloads, there's only two bullets
missing from the shotgun. You'd only want the
loop section to run twice for putting in
the bullet twice. But maybe sometimes when
the character reloads, they need to put in six bullets. So now you need a loop
section to run six times. Now we can do this with
the looping section and using blueprints to control
how many times it runs. So if we head back to the
ThirdPersonCharacter, I'll show you some of the nodes that we can use to actually control the different sections that are montage
is going to play. So we'll head back to the
third-person character here and start with, if you remember, we've got
these starting section. Now, if we wanted to, we could
just have our montage play that loop section straight away instead of playing the
default section first, we could loop section here. Now if we compile it and play, it won't even play
the reload anymore. So it will press one and you
can see it just skips that default section and go
straight to our loop section. Then we can head back to our
ThirdPersonCharacter here. Now to get access to our
different montage functions, we need to get an a reference
to our animation blueprint. To do that, we'll drag out from the mesh components, search, for instance, and use the
get anime instance node. Now, this gives us a reference to the Animation
Blueprint we're using. So for us that's the ABP money. Now if I drag out, I
can actually just get variables that exist
in this blueprint. To do that, we would
need to cost to it. So we could cost to ABP money. Then from that we could
get variables that are stored inside that or
functions if we wanted to. For example, get should move. That's a variable
that exists inside our animation blueprint here. But to control our montages, we don't actually
need to cost because these functions are built into
all animation blueprints. So we can delete these
functions for now, and we can drag out from the return value and
search for montage. And this will give
us access to all of the different
functions that can be used to control montages. Now one of the more
commonly used nodes with sections is the
jump to section note. So if we create
that, you can see that we get a
section name input. So this is where
we would put which section we want our
montage to change to. We can also specify a montage. Now, if we don't
specify a montage here, what will happen is if you have multiple montages playing
at the same time, and they all have the
same section names. It will change all
of your montages to that section that we put her. Now if you just want it
to happen to one montage, say our rifle reload, we would just specify
the montage it, we want it to happen too,
so we can select it here. And now we will only change this section for this montage. So we could set up a
quick demonstration. If we right-click
search for input. We'll add that and
we'll take pressed plug this into the montage
jumped to section. And we're going to
change this to default. Default like that. Now when we compile
and hit Play, if I press one to play, our montage can
see that it's just skipping straight to
the loop section. But if I press too, you in C, it's actually now playing
the default section. Now there are lots
of other things we can do with these functions. So if we head back to
the ThirdPersonCharacter and delete this montage,
jumped to section. We can drag out and
search on touch. I'm not going to be going
through all of these. Most of them are fairly
self-explanatory. And if you need a tool tip, just hover over and it gives you a pretty good explanation
of what they do. But an important one
is stop montage. And this allows us to tell
a montage to stop playing. So if we click on
stop montage here, we get a node that allows us
to set the blend out time. So maybe you just want the montage to stop
instantly here. You could just set this to 0 and the montage will
completely stop instantly. Or maybe you wanted it
to blend out slowly. You could put a time
here and it will slowly blend out
of that montage. Now again, you can
set a montage here. If you don't, it
will just stop all of your montages that
are currently playing. If you do, you can just specify which montage you
want it to stop. So if we connect this up
to our two input here, we've told it to stop
the reload montage. So we'll compile, hit Play, press one to play that montage. And if I press to, it, instantly stops up montage plan. Now lastly, I wanted to
show you how you can adjust the blending and blend out
times for your montages. So we can test this out. We'll go to our montage here, and I'm going to
actually just delete our loop section and delete
this animation as well. Just so we've got the reload now playing over here in
our asset details. And again, if you
don't have this, you can just go to Window and find asset details
to take it on. We've got the blending
and blend out times. Now, the high these values are, the longer it will take
for the animation to blend them fully and
then blend out fully. So if I was to set these
to say 00 like that, we'll go back to our third
person template here. I'm just going to get rid
of this styling section. And we're not going
to stop the montage, which is kinda let it
finish on its own. So we'll hit play. And if I press one, you'll
see that it starts instantly. There's no transition a tool, and it ends instantly as well. So we'll press one
and you see that it ends and starts very quickly. But if we want smoother
transitions into our animation, we can increase these values. So say 0.30.3 here as well. If we go back, hit Play,
and now when I press one, you'll see it
transitions much more smoothly to and
from the animation. So these are settings
that you'll probably use quite a bit with montages, because if you have
a quick montage, you might want the transition in and out times to be shorter. And if you have a long montage, you might want longer ones. The last thing I wanted to cover was the anime store manager. So if we x out of plane editor here and open up
our SK mannequin, then go to Windows and open the anime slot manager that will bring up the animation
slot manager. Now, here is where we
can add new slots or delete or rename existing slots. Now you may notice
that the name is shown up here are
actually the same name. So sharp when we select
the slop, no tip. These are the slots that are
defined in our skeleton. So this is where we actually
manage all of those slots. Now something to keep in mind
with slots and groups is one group can only have one montage playing through
all its slots at a time. So for example, if the full body montage slot
was playing a montage, and then I played
another montage using the upper body slot
that would actually cancel the full body montage. And the reason for that is
that both in the same group. So if I wanted my
full body montage and my upper body montage to be able to play at the same time, I would need to move my upper body slot to a different group. So I could either
create a new group or move it to an existing one. If you want to move a slot to an existing group, you
can just right-click, do set up a body group two, and that will give
you a list of all of the existing groups that
you can move that slot two. Now that's it for this lesson, but we will be using montages a lot more in our future
lessons as well.
47. Animation Blueprints (Blend Nodes): Hey everyone. In this lesson we're
gonna be taking a look at blend nodes. Now blend nodes allow us to play multiple animations on our
character at the same time. They also allow us
to use variables to control what section of
our Anim graph is playing. So before we get started, I am gonna be reusing
some of the stuff that we set up in our last lesson,
the montages lesson. And if you remember from
that lesson when we hit play and press one to actually
play our animation, if we start moving,
our lower half of our body doesn't move. And that's because I reload animation is actually
taking up the whole body. So today we're gonna
be using a blend know to split our body in
half so that we can have our movement animations
play on the bottom half while the reload animation
plays on the top half. So we'll start by
exiting plan editor. Then we'll head over to
our animation graph. So we'll go to characters
than mannequins, animations, and we'll open up the ABP
money animation blueprint. Right now here in
our animation graph, what is happening is our
locomotion state machine is outputting either an
idol or run animation. We're caching that animation
in this locomotion pose node then inside our main state machine or locomotion
state as playing. And that is just playing what we cached in the locomotion cash. Then if we head back
to the Anim graph, that locomotion
caches output from our main states machine
into this montage slot. And if you remember from
the montage is lesson, this is what's actually
playing our montage. Now, once the montage
has been told to play, this will actually just
output our montage animation. It's not going to play are idle or running
animations anymore. Then lastly, it goes into our
control rig and that's why our foot placement
actually still works when we're
playing the montage, because this happens after the montage has been
taught to play, and then we output
the final pose. So basically what we
need to do is here we need to add a blend
mode that will allow us to blend the top half
of the body playing the montage slop and
the lower half of the body playing the
locomotion cash. So to do that, we're
going to right-click and search for blend PER. We want layered blend
per bone like that. So now we need to
connect this up. I'm just going to
move these nodes back a little bit like this. And we'll drag this node in here and we'll disconnect
these two nodes. I'm just holding Alt and
then clicking less pen here. So first we will take
the output pin and just plug this into our
control rig like that. Let's move these up.
Now the base pose input here is gonna
be the animations that will play on the
lower half of our body. So we don't actually
want this to be the locomotion cash because that won't have our
jump animations. We need a cash from
our main states. So to do that, we're
going to disconnect the slot here, move this down. We track out from mainstays. I'm going to search for cash and click New, save cash pose. And we can select this node and call it whatever you like. I'm going to call mine, say main states, cash like that. Then I'm going to
move these up here. So they're a bit more out of
the way. Then we'll compile. Now, don't worry
that we've gone into a T-Pose here or that
we've got a note here That's just because
we don't actually have any animations
plug vignette. So now we're caching
or mainstay pose. We can drag out from our base
poster, search for main. And we can use the
use cached pose, mainstay cash like that. Then we want to copy
this, paste it. And now we want to plug
that into the source of our slot and plug that
into the blend pose is 0. Now blend pose is 0,
or they're going to be the animations that play on
the top half of our body. Now, all we're
doing here is we're getting our base animation. So our main state animations, this is our Idle run
and jump animations. These will always be played on the lower half of our body. And then for the top half
of our body, we're saying, if we're playing a montage, use the montage
for the top half. But if we're not
playing a montage, we just want to use those same
main state cash animation. So again, Idle run
and jump animations. So now we can compile just
to get rid of this note here and you can see our
animations are planning again. But right now, our animation is actually won't
split like we want. They won't split in the middle. We actually need to set that
up in the layer setup here. So if we select the node, go to Layer setup, then click these
little dropdowns. You can see that we
have some filters and this is where we actually define at which bone we
want our body to be split. So we're going to
add a new entry here and click the
index drop-down. And this is where
we actually set the bone that we want
the split to happen up. So for us we want to
turn on our bone names. We can find exactly which
bone we want to use. So we'll go to Character, then down to bones and we want to take on show bone names. So we'll take that on.
And now we can zoom in and we want the split
to happen on the spine. So we're going to zoom
in a little bit here. And I think spine one is
probably the best one to go for. Our logo animations will
play below spine one. Then our upper body animations
will play above that. Now, depending on
your character, you might have different
names in the future, so you don't always
put spine one. You'd need to check what the spine bones are for
your specific character. So for now, we're going to use spine one and we need
to make sure that we spell the name exactly the same as how it is in the skeleton. So spine underscore
01, like that. Now there are some
other settings for this note that I will go
into in a little bit. But for now, we're just
going to compile and we'll test this out and
game so we'll hit play. And if I press one to play our
reload and I start moving, you can see our
reload animation is playing and our lower
body animations playing. And when we're not playing
that reload animation or upper body animations
are just playing normally. Now this is just a simple
example of how we can actually set up different animations to play on different
parts of the body. Now, to explain a little
bit about the blend depth, this is basically
like a blend effect. So currently it's 0, which means from spine one and including
the spine one bone, all of the bones above it. We'll just be using this
animation output here. When I reload montage is playing a 100% of all
of the bones above. We'll be using that montage
and only that montage. Now, if we were to set
this to say three, for example, what would
happen is our spine. One would be using
about 33 per cent of this animation outputs. So 33% of our reload montage, then spine two would
be using 66% of our reload montage and 33% of
just our main state cache. And then by spine for
it would be fully using the montage for reloading. So you can basically use
these as a way to blend the effects of the blend
node between multiple bones. Now if we wanted to exclude
part of the upper body from actually playing the reload
montage, we could do that. So if we added in
another branch filter, open this up and set
this to say lower arm. So I'll say lower underscore. I set the bone depth
of two minus one. What this means is we're telling the blend note that we
don't actually want the lower arm bone or any bones below it to use
our blend state pose 0, we want it to use our base pose. So if we hit compile
and test this out, if I press Y and you can
see that my right arm isn't actually moving with
our reload animation anymore. It's just staying there. Now, the arm, the
upper arm is still moving because we're only
affecting from the lower arm. But you can see that it doesn't actually animate the
way it should anymore. So this is how you
can exclude parts of the body from
playing an animation. Now, don't worry too
much if you don't fully understand that when you're getting started with animating, most of the time
your bone depth will just be 0 and you won't really be using this minus
one option very often either. So for now, we'll just remove
this lower on one just by clicking the little down
arrow here and doing Delete. Now we can add multiple
input blend poses. So if we click Add pin, you can see that's added
as a new blend pin posts. And if we go to the detail, so you can see
that we've now got a new index here on
the layer setup. This just has the same
settings that are index 0 has its just that these
settings now for this pen. So maybe for example, you wanted the reload
animations play on the top half of the body, but you had a second animation that you wanted to
play on the face, for example, you could
then add that in here, add a new bone to the filter
on the branch filters, and then have the head play
a different animation. Next up we've got
the blend weights. Now this is the amount that the blend pose will actually
affect the base posts. So, for example, currently
is just set to one, which means that if for any bones that want to play
the blend pose one animation, it will play at a 100%
of that animation. If I was to set this to 0.5, we'll remove this blend
pose one pen for now. So what's right-click
and do remove blend pin. Then we'll compile if
we hit play now and I play our reload
animation by pressing one, you can see that it's not
fully playing the animation. It's basically using half of the effect of that
on our base pose. Now we can also use this to
disable a blend, for example. So we could set this
to say 0 and compile. And now if we hit
Play and I press one, you can see they
are no longer plays a montage because we've
set that Alpha here to 0. This is just a
normal float input. So we could drag out, use a remote to float option, and that will just create
us a float variable that we can change and control
inside our Event Graph. Now, moving on, if
we head back to the Anim graph and select the
layer blend per bone node. Over here we have an option for mesh based rotation blend. This basically means that
the rotation of our bones or use the mesh space
instead of the local space. Now this option
can be helpful if your animations look a bit weird when you're playing them. More often than not, I find that I actually have
this turned on, but it's going to depend on your character and the
animations that you're playing. This does the same
thing, but we've scaled so it will
use your meshes, bones scale instead
of the local scale. Most of the time you'll
want this turned off. Now there are other
types of blend nodes. So if we delete this one for now and we'll delete this
variable, right? Because I can search
for Blend tool and there's a blend
poses by Boolean. So if we create that,
you can see we've got a true and a false pen. So it will plug in our
source, it like that. Now, this allows us
to basically control which animations they're gonna played depending on
a Boolean value. So if this active
value here is true, that the animation is
connected up to true will run. And if this is
false, the animation is connected up to
folks will run. And we can actually see
this in the preview here. So you can see that
the value is false. So only the animations
coming from our folks pen here are being passed through to
our control rig. If I was to take
this on and compile. I will say now only the
animation from our true pen, it's being passed through
to our control rig. And then we have
some blend times. So if you were to change
this value during gameplay, the high these values are, the more time it takes
for it to smoothly blend from the true poses to the folks poses
and then back from false to true for
the false been time. So this node can be
really helpful for say, if you had a bunch of animation, so only play when your
characters swimming and then other animations
when the character is walking around on the ground, you may have a variable called his swimming that connects
up to something like this. And then that can smoothly transition between
you're walking on ground animations and
you're swimming animations whenever that Boolean gets
set to true or false. Another similar node
is the blending. So if we search for
Blend and then int, we can use the
blend poses by int. Now this works similarly, but instead of a boolean, it's a int value. So we can add multiple inputs
right now there's only two. So if I was to set this to one, then our one post would be used. So we can connect
these up like this. Hit Compile and you'll
see that the one is used. But if I change this to
0 and we compile again, you'll see that now the
0 inputs being used. And the good thing
about this is we can have more than two inputs. So if we right-click and do, or we right-click
on the node, sorry, and do add blend PIM. You can see that
adds a new option. Now, if I was to just copy
and paste these nodes, paste them, connect
them up to here. And now let's set this
to two, will compile. You see that now the
two pin is being used. Again, we've just got
these been times and they work the same way as
our Boolean node. So whatever value you put here is how long it will take to
blend it into that pose. Now we can also use a
blend node using an enum. So if we delete this and we can pull out and we'll just leave
it like that for a moment. We'll create a new
enum, so we'll right-click and go
to the blueprints, Then go to enumeration. I'm just going to call this E
underscore animation types. We'll open this up and
we'll create a new anion. And we'll call
this say swimming. And we'll add another one for walking and another
one for say, car. Now these are just examples so I can show you
how the code works, but we'll close this for now. Go back to our animation
graph and then we'll search for EA
underscore animation. You see at the top
here we've got blend poses E underscore
animation types. And that's because
that's what we called a union. So we'll create that. You see that we get
this node here. And if we right-click
on the node, you can see that we can
add pins for swimming, walking, and in cost. So we'll do that for
each one like that. And now we've got an anion pen instead of a boolean
or an integer. So we'll connect the output
up to our control recap. And we'll connect
these up safe for swimming, walking, and capos. Now currently this is set to 0. So if we compile,
it will just pick the swimming post because
that's the first one. But we can also use a
variable to control this. So we can create a new anion. We'll call this animation
mode for example. And we'll set it to E
underscore animation type. That's the union
we've just created. We'll compile. Now we can plug this
variable into our node. We can actually control
which one's gonna be used using this variable. So we can say, I want in car, compile it and now
it's using the ink up. And we can change this during gameplay in our
event graph here to control which animations
we want our graph to play. And then lastly, if we delete this node and we
search for the land, we can just use a blend mode. Now, this is a simple node
that basically just takes an a and B input and allows us to blend between them
using an alpha value. So if this is 0, it'll be, the output of this node
will just be 100% of a. And if this is one, it'll be a. 100% of B is 0.5, then it'll be half
and half of both of those animations outputted. For now, we'll just delete this node and we're actually just sat back up our layer
blend per bone nodes. So we'll search for lead
and we can use lead brand per bone will connect
this up to here again, this up to our control rig. We'll delete these nodes because they're not using them anymore. Then in our note here, we'll just set the
branch field curb backup for spine one. So it will set this to
spine, underscore a one. And we'll delete these variables down here as well because we're not actually using
those and just compile. So now when we hit play
and we run around, we can press one
and it will play us a reload animation while our movement
animations are still working with them
for this lesson, hopefully you now
understand a little bit more about
blending animations together and how we
can actually play two animations at the same
time on one character mesh.
48. Animation Blueprints (Notifies): Hey everyone. In this
lesson we're going to be taking a look at
animation notifies. Now animation notifies a really handy tools
because they allow us to run code a specific
time in an animation. Now we've already looked at some notifies earlier
on in the course. We looked at the play
sound and play effects, notifies which allowed us
to play sounds or play particle effects at specific
points in our animations. I will quickly go
over those again in this lesson just to
refresh your memory. So to start with,
we need to go to either an animation sequence
or an animation montage. We can add notifies to both. So I'm gonna be using
the reload montage that we've been playing
in our previous lessons. So we'll head over to
the lessons animations. And if you don't
have this folder, I explained how to add these
in the montage lessons. So you might want to go
have a look at that. Now, we'll scroll down and find our reload montage, which
is here at the bottom. We'll just open that up. Now. Down here we have our notifies timeline
and this is where we will see all of the notifies
for this specific montage. To add a new notified, we just right-click
on this bar here that says one and we
can add a notify. Now the engine has some
built-in notifies already. And that's how we can
play sounds or play particle effects or
Niagara particle effects. Now there are other notifies, as you can see here for Clothing Simulation
and stuff like that. I'm not going to be
covering them in this lesson because
they're pretty specific and a little bit more advanced and what we're
gonna be covering. But we'll just add a
play sound notify. And now with that
added, we can position that at any point
in the animation. So say we wanted to sound
to play at this very point. We could add our
notified to this point. Then over in the Details panel, we can set a sound, volume
and pitch modifiers. We can change what
the notify color is, and this is just
for organization. So you can quickly, at a glance see what a notify
is by its color. Another useful setting here
is the trigger chance. Now, maybe you only
wanted this sounds play sometimes when this
animation plays randomly. So what we could do is
instead of sending it to one, which means the
sound will always play when the animation plays. We could set this to say 0.1. Now, this sound, we're only play ten per cent of the time
that this animation plays. An example of how this could
be handy is maybe you have an idle animation and
you wanted to add a cough sound to
that idle animation. Now, you probably don't
want that sound to play every single time the
idle animation plays. So you could set the
trigger chance for that sound notify to 0.1, and that sound will play 10% of the time that the
animation is played. Now, moving on, we can do the same thing with
particle effects. So I'm going to delete
the sound notify here, right-click and do add notify. Now we can either add a
nine to five for Niagara, political effects will cascade. I'm going to select Niagara just because that's
a newer system. So we'll click that and
select that notify. Then up here in
our Details panel, we can set which Niagara particle effects
we want to choose. I don't currently have
any of my projects, so there's one coming up here. But if you did, this is
where they would show up. Then we can set the
location and rotation. Now, this is the
offset from the root. So the root bone
on our character here is right where my
mouse is currently. So if we were to
add, say, 50, Hi, our particle effect would move up to about this
height because it's increasing the height of the particle effect
by 50 from the root. Now, we can also
say whether or not our political fact it's
attached to something. So currently it's
attached and that means it's going to just
attach to the root. But we can specify a
bot name if we want. We wanted the particle effects
be attached to the head. We could do that by
searching for head. And you can see that gives
us our head bone here. So now when we spawned
this particle effect or will actually be
attached to the head bone. Unlike before, we can
say notify color. And we can also
change whether or not the notify will run every time or say half the time
if we put 0.5, for example. Now, using this type of
Notify to play effect, it'll basically just
tell the effect to play once and then the effect
will be destroyed. But maybe you wanted the
effects you run from say here to here in the animation.
Well, we can do that. So we'll select this
notifying, delete it, right-click and
we'll go to notify state and go down to
time to Niagara effect. Or if you're using cascades, time to particle effect. So it will select the
Niagara option here. And you see that
now we've got a 12. We can actually drag
this to value here by clicking the little dot at
the bottom and drag that out. So we can add this to say 50. So now the particle effects
we set for this notify I pair one from the one
value to the true value. Now something to keep
in mind with this is your Niagara effect will be, will need to be set up to loop. If it's only set up to run once, then the particle effects will just run once and then
it won't do it anymore. So you will need to
Niagara particle effect That's actually set up to
loop for this to work. Then we've got the
same settings as we did with our previous
notify type. We've got the template
that we want to use. So this is where we set
the effect that we want. We can choose whether or not it attaches to a bone or socket. We can set its location
and rotation offsets. We can choose whether or not
it destroys immediately. And basically what
that means is, say your effectors looping
as we play the animation. Once it gets here, if destroy
immediately is ticked on. It doesn't matter what stage the particle effect is insets
halfway through running. It will be destroyed instantly. Whereas if this is ticked off, then once we get to
this point, if the, if the particle effect
is halfway through, then it will let it finish. So maybe your pot, a cool effect takes two more
seconds to finish, then it will allow that. So it's up to you whether or
not you have this tectonic depending on the type of
effects you're using. Now when working with notifies, you might end up with quite
a crowded timeline if you have a lot going on in
a specific animation. So you can always just
add new notify tracks. So we can click this
little drop-down here to add notify track. And that gives us a second track that we can add notifies two, it doesn't change how
they run or anything like that is purely for organization. Now, so far, we've been using the default notifies that come
built-in with the engine, but we can actually create our own that allow us to run at events and run code when an
animation notify is run. So what we'll do is we'll select this notify
and delete that. Now, maybe I wanted
a piece of code to run when my character say grabs the magazine or pose the magazine
from the weapon here. Well, we can do
that with notifies. So what we'll do is
right-click and do add notify. Then we'll go up to new notified and that'll let us
name the notifies so we can pull call this detach
magazine like that. You can see we've
now got a notify that it's called
the Touch magazine. We can move it about
like our previous ones, but I'm going to keep mine here. So now this notify will allow
us to call an event inside our animation blueprint whenever this animation plays this point. But we are going to run
into a small problem here, and I'll show you why if we head over to our Animation Blueprint, which if you remember,
is in characters, mannequins animation. And then we'll open up money. Now, normally if
I right-click and I searched for my detach, I should find an event for our detach
magazine, but I'm not. And the reason that's
happening is if you remember, are less than animations
and this folder here actually have
their own skeleton. And then our character
has a different skeleton. Now this is why our notify. It isn't just showing up in
our animation blueprint. We can easily fix this. So what we need to do is go
to our Characters Folder, then to our mannequins, then two meshes and open
up the SK mannequin. And in here, we're gonna go to the Animation notifies tab. If you don't have it
open, you can go up to Window and find
the animation, those FISA and take it on. And we're just going to
right-click and do new. I'm going to call this magazine, oh sorry, detach magazine. And it needs to be
spelled exactly the same as the notify
in our montage. And now we've added that
new notify to our skeleton. So now when we go to our
animation blueprint, we can right-click
search for the touch. And you can see we've
now got a then anime notified to touch magazine
and we can add that. Now if you were to
add a notify to an animation that is using the same skeleton
is your character. So to give you guys an example, we'll go to the
Characters Folder, mannequins, animations. Then we'll go to money
and we'll just find the will find the land animation for example, I open this up. Now if I right-click
in the notifies here to add notify, new notify. And I'm just going
to call this jump. And now if we go to our
Animation Blueprint, I right-click and
I search for jump. And you'll see that that's
just shown up right away. And that's because I'd
jump land animation is actually just using the same skeleton
as our character. Now, in our reload montage, we've got our detach
magazine notify, and then we've also inside our Animation Blueprint got
that event here as well. Now, this event will run every single time that this montage is played by our character and the animation
gets to this point. So to test this out, we can
just add some code to this. I'm just going to drag out
and do a print string. And we'll just leave
this sang Hello. And we'll compile, hit Play. And now when I press
one, you'll see that we get that hello print out when our reload animation
gets to that specific point. And we can also check that
the jump end is also working. So we can right-click
search for jump, and that creates us a new event. We can drag out from that and
do a print string for that. And if we compile, we
jump when we land, you can see that that Notify
is also running as well. Now, just heading back to our characters
skeleton for a second. We'll go to mannequins
than meshes and open up the mannequin here in our
animation notifies tab. Here's where you can
delete animation notifies. You can create new ones so we
can right-click and do new. We can also rename as well. So we can right-click and select Rename to change the
name of a notify. Another helpful tool is
the find references, and we can use this
to find all of the animations that
have this notify in it. So if we click this, you
can see that it's giving us the exact animation that
uses the jump and notify. We can double-click
this and you can see that's the animation
that has that notified. So it may be, for example, you have an animation
that's running and notify that you don't want to. You can always just
come to the skeleton, right-click the Notify and find the animation that's
playing that notify. If you want to get rid
of the search here, we can just right-click the
remove filters and you can see that now it's showing up
all of our animations again. Now we can also
create our own custom notifies the work a little bit like the play sound or
play particle effect notifies. So if we head back to the
content browser here, I'm just going to go to
the Blueprints folder. So third-person
blueprints, we'll right-click and click
Blueprint class. Then we're going to go to all classes and
search for notify. And we want animation
notify here. So if we click that
and do Select, that'll create us
a new blueprint. I'm just going to
call mine example. Notify like that. And we'll double-click
to open that up. I'm just going to
drag mine up to the top bar here like that. Now we've got a
new editor layout. You can see that we
don't actually have an event graph where we have is our My Blueprint Panel and then the Details
panel over here. Now we've got some
functions built into this blueprint
that we can override. And these are the functions
that will actually be run when the Notify here is run. So what we'll do
is first of all go to our reload montage. If we right-click in the Notify, but go to add notify. Over here you can
see that we've now got that example notifies. So if we click this, you can see we've got a new notify type. That's the same as our
blueprint name and we can position it where we want
to say here, for example. So now when our animation
gets to this point, it will run the events inside
our example notify here. So using this, we can run
custom code inside this notify. Whenever that notify gets ROM, we can go to overwrite
receive notify. This function will
run whenever I notify inside our
animation gets run. And it provides us with
some useful information. So it provides us with the
animation that actually called the Notify and
also the mesh component. And the good thing about
this is we can access, say, our animation blueprint or even the character that played
the animation using this. So we can drag out and we can
do gets owner, like this. Now, the owner of the character mesh will always be the
Character Blueprint. So using this, we
could drag out and do cost to character, for example. And now we can easily access
our character blueprint. We can also access our Animation Blueprint
just by dragging out from the mesh components,
searching, for instance. And that will give
us a reference to our Animation Blueprint. So just to give you
an example of how this actually works, we'll
delete this for now. I'm just going to add
a print string here. And we'll put say hello. This is a test. We'll connect this up
to the return value like that will compile. And now when we hit
play and I press one, you'll see that hello
and also runs out hello, This is a test and that's because inside I
reload animation, we have our new example notify. And inside on example notify. The received notify of them runs and it runs our
print string here. Now a common example of what these customer or Pfizer
used for our footsteps. Now you may be thinking
you can just use the play sound to notify that's
built into the engine. But the problem with
that is if you have different types of sounds
for different ground types, you would need to detect what type of ground
your character is walking on and then play
the appropriate sound. Using a customer
notified like this, you could write the
code that maybe does a line trace underneath your character to detect
the ground and then play the correct sound
for that ground type. But this is just one example. You could use these
for all sorts of things in your projects. We can also add customization
settings to them as well. So if we add a new
variable here and we'll call this say
sounds, for example, we'll go down to the variable
type and we'll search for a sound base and select
object reference. Now, we'll compile and we'll just click on the
little eye here. Or you can take on
instances editable here, does the same thing,
will compile. And now when we go to our reload montage and we
select our notify, you can see up here
in the settings we now have that sounds variable
that we just created. We can set a sound and then inside are received
notify function. We could use whatever
sound is set inside the montage
it and play it. So to do that, we'll
just drag out from our return note here and
we'll make some space. So we'll drag out and we'll
search for play sound. We use play sound at location. We'll grab our sound value and plug that into the
sounds variable. And for location will get
the Mesh Component location. So we do get location. We won't get world location. Plug that into location. So then we'll compile
it and you'll notice, I'm going to leave my
sound here as none, and we'll use the montage to
actually set that sounds. So we'll select the example notify here and pick
a sound up here. So I'm going to pick the
compile failed sound. And you'll actually notice while the animation plays in here, it actually plays
a sound for it. So we'll stop this plane
because it's getting annoying. And we'll test this out. So we'll hit play and
the game and we'll press one to play that sound,
will play the animation. You can see that our notify
is running and it's playing that sound that we sat
inside our montage here. You can do this with
all kinds of settings. So if you wanted
to, you could add a Boolean, for example here. And as long as you take
instance editable, that'll be accessible
from our montage. You can see that now we've
got that new variable here, and I can access it if
I select my notify. And we can also use multiple
of this animation notifies. So I can move this over
here, right-click. Add enough one example. Now if I select this and now
we can pick another sound. So I could pick the compiler
success, for example. Now, when we hit play and I press one
to play the animation, you should hear both sounds. Lastly, I showed you how to create new animation notifies, but I didn't actually show
you how to reuse them. So if we exit out of
plane editor here, go back to our reload animation. You can see we've got
a detached magazine. Now, maybe I want that event
to run as well over here, we can right-click, do add, notify, go to Skeleton notifies. And over here you can
see we've got all of our existing notifies
and are detached. Magazine is just at the bottom here. So we can create that. Now the event inside our animation blueprint here will run twice for
this animation, once here, and once here. And we can also use this detach magazine notified
in that other animations, it isn't locked to
this animation. So if we wanted to, we
can head over to say, the Animations folder underneath the mannequins, then goto money. And we could add this to the
land animation for example. So we can right-click and
notify, skeletal notifies. And then we can go down to
the detached magazine here. And now that event
will also run when we play this jump land
that animation as well. So that's it for this lesson. Hopefully you now understand
a little bit more about animation notifies and how you can use them in your
future projects.
49. Animation Blueprints (States): Hey everyone. In this lesson we're gonna
be taking a closer look at the animation states inside
our Animation Blueprint. Now in our first lesson, we did a quick overview of
these animation states. But in this one,
we're going to take a much closer look of how they work and how
you can add new ones. So to start with, just open up your animation blueprint
and head to the Anim graph. So we will just open that up. Then we're going to
start by going to the locomotion
state machine here. And if you remember from before, here is where we
have our idle state and then I'll walk
slash run state. And within these
states is where we actually have our
animations place. So in the idle state we have the idle animation and
then the walk slash run. We have our walk slash
run, London space. So to begin with, we're
just going to add a new state to this
locomotion state machine. So to do that, we'll just
right-click and click on state. And that'll create us
a new state similar to our idle and our walk
slash run states. I'm just going to
call mine aimed and we're going to create
an aim state today. So why now we have a
new state called aimed, but it will never actually
be called at the moment because we don't have any rules that will transition to it. So to create a new rule, we need to drag from a different state
towards our new stapes. So we're going to drag
from idle to aimed. That's going to give
us an arrow that points from idle to aimed. Because this rule determines
if we're in the idle state, whether or not we should
move into the aimed state. Now we need to actually add some code to our
rule to determine when the idle state should
switch to the aimed state. So what we can do is double-click on this
little button here. And that'll take us
inside that rule. And depending on whether or not this return value is true, is whether or not we will transition from idol
to the end state. So we'll start just by
creating a new variable. I'm going to call
mine aimed, or sorry, we can't call it aimed because
we have a state name name, so we'll call it is
aimed like that. I'm going to change mine to a Boolean like that
and we'll compile. Now you might get
a warning here. All that's doing
is telling us that our rule here has no code in it. And we're going to add
some code to that now. So we're going to double-click
this to open it up. And we're gonna take our
is aimed and just connect that up to the result here. Then we can compile like that and we should get rid
of that warning now as well. Then we'll head back
to the locomotion. So now we have a rule that will allow us to transition from idol to aim to whether or not r is aimed variable is true. We can actually test this out. So if I take this
on, you can see that our character T
poses and it's doing that because we
haven't actually set an animation in our state yet. So now we'll open
up our aimed state and actually add an
animation for it to play. So we'll drag out and
search for play players, and we will use the
Sequence player. Now, this allows us just to set an animation that our
aim state complaint. And we can do that over here in the Details panel will set the sequence to
something like the ADS. And we should find
the rifle idle ADS. If you don't have
this animation, we actually went through
how to import them into your project in the
montage lesson. So you can take a look
at that and that will show you how to add
those animations. And so now we've set the
animation if we compile, because our aimed or is
aimed is set to true, you can see that
it's now playing a rifle aimed animation. But the issue now is if we head back to our locomotion
state machine, if I was to change or
is aimed to false, our animation doesn't actually
switched back to idle. That's because we still
need to create a rule that goes from our aimed to our idle. So we'll drag from
aimed to idle, and this will be
checked whenever we're inside the aimed state. So now we need to add some
code to this rule that makes us change back from our
in-state to our idle state. So we'll open this up. We're going to grab
the is aimed variable. Now we want this to return
true if this is false. So we'll drag out and
search for naught, will find the NOT Boolean here and connect that
up to the results. So if is aimed is true, this will convert it to a false and then return
a false value. And now we can test this out. So I'll go back to the
locomotion view here. We'll select is aimed and
we'll take it off and out. Firstly, we need to compile. So now when we take it
on and we take it off, you can see it's switching
between our two states now. Now our transition metals
have a few other settings. I'm not gonna go
through all of them, but I'll go through
some of the more important ones that are here. So to start with, we
have the priority order. Now the higher the value here, the higher priority
that role has. So for example, if you have multiple rules like we
do here for the idle, we have this one and
we have this one. Say both of these were to
be true at the same time, then the engine will
pick the one that has the highest priority here. This setting can be
useful if you have a much more complicated
locomotion system with a lot of rules going
from say, one state. Next we have the
transition duration. Now this is how long it
takes for idle animation to smoothly transition into
the aimed animation. Because if you notice, when
we select our name to, it doesn't instantly snap. We get that smooth
transition between them. So if we increase that
duration time here, say the transition rule
from aimed to idle, we change it to say one. Now, when we compile and we select as aimed,
if we turn it off, you can see that you
get a much smoother, slower transition from the
aimed animation to the idle. We can do the same thing
for our overall as well. So we can select that,
set the duration to one. And now whenever we
take on AMG will get that smooth transition
after we compile. There we go. So
all combined now. And you can see that now we get that much slower transition
between the two animations. Next, selecting our rule here. In the blend settings
we have a mode. Now this is how
the animation will transition to the new animation. You'd have to try these
out to see how they work. But these give you
different effects of transition between
the two states. Next, we have the notifications. Now these actually allow
us to run events in our Event Graph whenever
this rule does something. So we can have start transition and we can have an event in our event graph that will run whenever this
transition here starts. So whenever the
rule becomes true, this event that we
name here will run. We've got end transition. So when the transition
is finished and we're moving into the new
state, this will run. And then if it's
interrupted, this will run. So if, for example, we will 1 second into
transitioning from idle to aimed, and we canceled it. The rule became false
and we went back to idle than are interrupted,
event would run. So to give you a quick example, we could just write test here. For example, compile, go to the Event Graph and
if I right-click and search for test, or sorry, event test will find that new anime notify underscore
test and this event will run whenever our rule here begins its transition
from idol to MD. And if you can't find your
event and the event graph, don't forget that you
do have to compile your blueprint after
you write a name here. Now we have similar
settings for our state. So if I actually select
my aim state here, you can see that we've
got those same settings, so we've got a custom event that we can run it in
our event graph for when our aim stay is entered and also when that
aim state is left. So again, like before,
if I add a new event, I'll call this aimed started. We'll compile, go to
the Event Graph and I'll search for event aimed. And you can see
we've got our event aimed started here as well. So now we've added a new
state, so our locomotion, and we've added the rules to transition to and
from that state, but we haven't actually set up any code to control
this variable. We've just been manually
changing it in here. So I'll show you a couple
of ways that we can control variables in our
animation blueprint from the Character Blueprint. So to start with, we can
go to the Event Graph. It will find the blueprint, update animation,
and this will run every frame and update the variables that
we connect to it. So we can add a new branch here. Then we'll get our character because we want to get
some information from our character will
drag out and we can do cost to the person, connect up to the sequence it. Now we actually need to add a naming system
to our character. So we'll compile it and go
to our character blueprint, which is in the third
person blueprints than third-person character. Now, don't worry too much if
you don't have this code. This is from our
montages lesson. So we'll just scroll up here. I'm going to right-click
and search for left mouse. And we're going to use
left mouse button. And we'll create a new
variable called is aimed. Like that. We want to get that
drag out from it and do f. And if our aimed
is currently true, we want to set it to false. And if it's currently false and we want
to set it to true. So I'll just copy and paste
that and connect up to folks and take it
on here like that. And we'll compile, head back
to our Animation Blueprint. And now we can just get r is aimed from our
character blueprint. Use that to set R is aimed
in our blueprint here. Then we'll compile,
and now we can test this out so
it will hit Play. If I left mouse button, you can see that
we transition into that animation and we've still got that 1 second
transition time. So it's going a bit slow. So we'll head back
to our locomotion. It's like the rule. Change the duration, say 0 to do the same for
the other rule. So 0.2 here as well. Then we'll compile it, and
now we can test it again. And I'll hit left mouse button. You can see that we're
now transitioning to that animation. Now, this does work, but maybe you have a lot of code going on in your
animation blueprint. And you don't need this code to actually be run
every single frame. So what we could do
is if we delete this, we can actually set the code from our ThirdPersonCharacter. Instead. We'll go to the
ThirdPersonCharacter. We'll get our Mesh Component, drag out from that and
do get an M instance. If you remember, this gives us a reference to our
animation blueprint, but we still need to cost to our ABP underscore money because that's our
animation blueprint. And we're going to have both of these nodes run this code. So it doesn't matter
if we aim or unnamed. Then we want to drag out and
we want to do set ain't. Now allows us to set
our aimed variable. That's the Animation Blueprint. And we just want to
get r is aimed from this blueprint and
use that to set it. So now we can test this out
if I can pull, hit play, and when I left mouse clicking
and see that it's still working using that new code
that we've just written. Now you may notice if we left mouse button and
start moving around, we don't get any movement
animations anymore. Now that's because we
didn't actually set up any rules to transition
from our aimed. If we head back to locomotion from our aimed to
our walk slash run. So it's just gonna be
stuck in our aimed until we get rid of left mouse click and then
it will switch to idle. And if we are moving, it will then switch to walk. So we could add
some new rules here that transition from
aimed to walk slash rump. So we'll drag out from aimed and go to walk slash run like that. And we're going to use
the same code that we use from our idol here
where it says should move. So we'll open up that rule. We will get the
should move variable. This will be true. If our character is moving, then we'll head back to the
locomotion and will compile. And now when we hit Play, if I left mouse
button, you can see we aim and if I start moving, we transitioned back into our
walk slash run animations. And you see it if I exit out
of the walk slash running, we go back to our aims and we can uname, like we did before. Now, lastly, I just wanted
to cover stay aliases. So if we exit out
of plane editor here and head back to
our Animation Blueprint, stay aliases are
really handy to keep your animation states
little bit tinier. So we'll set up a
quick example of one. We'll right-click and
use a state alias and we'll just call
this aimed checks. For example, we have our
aim check selected here. We're going to
connect to our aimed. And we're going to
use this new rule to determine whether or not we should enter
the aimed state. So we'll get aimed and
connect that up like that. Then we're going to delete these rules here that connects
to our idle, to our aims. We're also going to
delete the rule that connects it to the
walk sash run. So now these two blocks
aren't connected. But if we select our
aim checks here, we can take on which states
we want it to run for. So we could take on idle and we could take
home walk slash run. What this means is if
we're in our idle state or our walk slash run this alias, we'll run this check. So we don't actually
need to have direct connections from
either one of these states. Two are aimed because
we're now using this alias with these
two states tectonics. So that when we're
in these states, this will run any of the rules
that are connected to it. Now we need to set
up a way to go from our aimed animations to
our idle or our walk. So we'll right-click
Add a new state alias. We'll call this movement checks. Using this, we're going to
create a rule to our idle. And this will be, is
aimed, needs to be false. So we'll drag out from his
aims and we'll do not. And we'll scroll
up and do not be limb and connect up here. And then for our movement
will drag out and we'll connect up to
our walk slash run. And we'll do the
same thing we want. Is aimed, is actually
we'll use should move. Because when we start moving, we want to just use our
movement animations to want should move to true. Now, one thing we do
need to add to our rule, entering our aimed as
we also need to add that we don't want it
to run if we're moving. So I'm going to
open up our here. We're just going to add an end. So we'll do and we'll connect
the output to our results. So we want and should move, should be true or
should not be true. We want this to be a NOT, NOT Boolean like that. So our rule here will only
be true if it is aimed, is true and if should
move is false. So just to give you
a very quick summary of what this does when we're in our idle or our walk
slash run states are aimed to check run. And it will do that
because we have those two states ticked on here. And it will run all of the
rules connected to it. So it's going to run this check. It will check is aimed to true
and is should move false. And if it is, then we'll
run our aimed animations. And then while we are
aimed animations running, this movement checks will
run because we've got, oh, I forgot to
actually take that on. We'll select that
and tick are named. So because we've ticked on our aimed whenever we're
in that state, movement checks will run
and that'll check both of these roles here to
see FEV1 are true. So now we will test this out. We'll compile, hit Play,
and now we can aim. And if I aim and start moving, you can see that
we start running those movement
animations instead. If we stop, we go into the
aimed animations again. That's just a brief
overview of the aliases. It doesn't really make a
lot of sense when we've got a small locomotion state
machine like this. But if you have something that's becoming more complicated, maybe you have a lot of rules
going all over the place. You can use these to tidy up
your animation blueprints. So that's it for this lesson. Hopefully you now understand
a little bit more about animation
states and rules.
50. Animation Blueprints (Blend Spaces): Hey everyone. In this
lesson we're going to take a closer look at
animation blend spaces. Now, if you remember from our Animation Blueprint
overview lesson, blend spaces that
I was to smoothly transition from one
animation to another. And we can take a look
at an example of this by going into our money
Animation Blueprint. Then we'll go to the Anim
graph than the locomotion, then walk slash run. And then here we've got
a blend space per node. Now, this node takes in a value like our ground speed
here and uses that to determine which
animation it should play from our blend space. If we select this node and go
over to the Details panel, we can find which blend
space it's set to use over here in the
blend space option. If you hover over, save the
name of the blend space. So ours is the MM walk run. We can also click
this button here to take us to that blend space. So we'll do that and
then open it up. Now as you can see, we've got
this graph view down here, and this is where we define our animations for
the different speeds. So here you can see
that the speed is 0, and up here the
speed is 500 For 0. If we hover over this dot, you can see the
current animation is the walk-in place animation. Then further along
at the 230 value, we've got a different
animation and that's our walk
forward animation. And then lastly at the end, speed 500, we play
or run animation. If I hold Control and move my mouse along the
timeline here you can see as the value increases,
our animation changes. So as we get closer to
our run animation here, you can see that it gets
closer to that animation. So this is what allows us to smoothly transition between say, a walk animation and I run animation and it uses
that speed value, which our animation
blueprint here is supplying, and that's our
ground speed value. Now, I'll walk run. Blend space is a 1D blend space, which means that only
has one variable that controls which
animation is playing. That's our speed value here. But we can also have blend
spaces that use two variables. We can have a direction
and the speed that controls which animation
is going to be played. It for this lesson,
we're going to set up a 2D blend space. So to do that,
we're going to head to the Content Browser. I'm just going to go to
the Animations folder. Inside the mannequins folder, we're going to right-click,
go to animation. And then you want to find
the blend space option. You can see there's
the 1D option here, or the blend space
here, which is the 2D. So we're going to
select that one. Then we're going to
pick a skeleton. I'm going to use
the skeleton that comes with the third
person template. So that's this top
one here you can see that the path is
four characters, mannequins and then meshes. So we'll select that and
that will nameless to aimed walk blend space. And we'll open that up. Now in here you
can see we've got a similar looking
graph you to our 1D. But instead of just having
the horizontal value, we also have a vertical
value that allows us to set animations
anywhere on this graph. And then we'll be able to
control them both with a direction and a
speed variable. So to start with, we need to rename and set up these axis. So we'll start with the
horizontal axis here. You can click the drop-down
if it's not open for you, we're going to name
ours to direction, because this axis will control the direction that the
animations we want to play use. Then we want the minimum
axis value to be one or minus one AT and the
maximum value to be 180. And that means we can
set an animation for every possible direction
that our character goes. Then we need to set
the vertical axis so you can just open
that down here. And we'll set this one to speed. Now, the maximum value I'm
going to set to say 600, and we'll leave the
minimum value to 0. So any animations we place
down here at the bottom of the graph will be used when our character is
idle or not moving. And then as we move up, the animations will be used for faster movement
speeds up here. Now something I like to do
is to take on the snap to grid option in the
horizontal axis and then the vertical axis. And what this will do is when
we drag in our animations, they will actually snap
to these grid points. Now, this is
personal preference, but I recommend having
these turned on. It just makes setting your
animations a lot easier. Now we're ready to actually set some animations in
our blend space. We're going to start
with the animation is used when we're at 0 speed. So for that, I'm
going to search for idle in our asset browser here. And I'm gonna be using
the rifle idle ADS. Now if you don't have
these animations, you can watch the beginning of the montage lesson and I'll show you how to add these
animations to your project. But if you do, we
can just drag this in and we want this to
be at the center bottom, so I'll just drop that here. We're also going to
add it to the bottom left and to the bottom-right
as well like that. Now the reason we do this is because this is when
our speed is 0, so our character is not moving, so our direction value
doesn't actually matter. All we need to do is have
our idle animation play. Next, we need a walk
forward animation, and this will be the animation that's played when
our direction is 0. So it will be at the top here. So for that, I'm
going to search for FWD and the asset browser, and we're going to use the
rifle walk forward animation. So drag that in and drop
that in at the top here. Now if we hold control, we can drag about and
we can actually see our walk animation
now working as we drag our value up to the
walk forward animation. Next we need our
backwards animation. So for that, we're going
to search will be WD. And we're going to use
the rifle walk backward. And we're going
to plug that into the far left point here. And also to the far
right point here. Now the reason we do that is because wherever
our characters at 180 direction or minus one AT both of those are going
to be going backwards. So either one we want to be playing that
backwards animation. Next we want our left animation. So in our asset browser, we're going to search
for left and we want the rifle walk left. So I'm going to drag that
into this point hip. And then we want the
right animation. So we'll search for right. And we want the
rifle walk, right? And that's gonna go
up here like that. Now when we hold control, we can control which animation
is going to play depending on our direction and
also our speed as well. Now we're going to use
this new blend space inside our animation blueprint. So to do that,
we're going to head over to our money blueprint. Now we're going to add a new state that's gonna be used when, where aimed and
while we're moving. So to do that, we're going to right-click and add a new state. I'm going to call this
aimed movement like that. Now we're going to need
a rule that goes from our aimed to our aimed movement. And inside this
row, we're going to check is aimed to true. And we're also going to
check, are we moving? So we'll do an AND Boolean
and we wanna get should move. So if both of these are true, then we return the result. And that will allow
us to move from aimed into our aimed movement. Now we want to
transition back to aimed from our aimed movement. We stopped moving.
So we'll open up that rule will get is aimed. And we want to check
is should move false. So it will get should move. We want to use a
NOT Boolean nodes. So NOT Boolean. And then back in the locomotion, we need to add a row going
from our aim to check two are aimed movement because if we're already moving and
we start aiming, we want to transition to
the aimed movement state. So we'll drag from aimed
check to aimed movement. And we'll open up our Rohit. And again, we're going
to get is aimed. And we also want to check is
should move true as well. So we'll get should
move like that. Then we'll head
back to locomotion. So, so far we've got a set up so that when aimed
checks is running, it will check all we aimed. And if we are, we'll
go into our aim state. And if we're aimed
and moving instead, we'll go to our aimed movement. Now if we're in aimed
and we start moving, it will move from aimed
to aim to movement. And if we're in aimed
movement and stop moving, we'll transition into
the aimed state. Now there are a couple of
other changes we have to make. We need to select our
movement checks, stay alias. We need to take on the aimed movement hip and
we're doing that. So we check if were
aimed and if we're not, then we want to
transition back to our normal idle or normal run animations from
our aim states. Now, we need to change
one of our rules connected up to
our movement check here, and that's this one here. So if we open that up currently, this is just checking
if we're moving. We want to change this because now we have a movement state. We don't want to
transition to walk slash run if we're just moving. So we need to add
a check to make sure that is aimed is false. So we want a Boolean
know for this. We'll drag out again and
will return this value here. So now if we head
back to locomotion, if we're in Ames movement
and we stop aiming, it will transition
back to our walk slash run because we
have this check here that checks is aimed false
and it should move true. And if it is, then it
will transition us from aimed movement or
aimed to walk slash run. Next, we need to actually set up our blend space and
are aimed movement. So we'll open that up. We'll drag out from the result
and I'm going to search for blend space player. And we'll use the blend space. Play a note. Then we'll select
it and we'll scroll down to the blend space
option at the bottom here. We need to set this to
our new blend space. So that's the aimed
walk blend space here. You see it's actually
updated our inputs for our direction and
our speed variables. So for speed will just
drag out and do get ground speed like that. Now, for direction, we
need a new variable. To do that, we'll head
over to the Event Graph. And in here we're going
to create a new variable. So we'll do that now and
we'll call this direction. And we want this to be a float. So we'll set that to
a float and compile. Now we need this to
update each frame, so we're going to add it
to the code down here. So we'll add a new
pen to the sequence, will create a set node. And we'll connect this
up to our sequence. I'm just going to
double-click on the line to create a reroute. Now, just to keep things tidy. So to get our direction,
we need our speeds. So we're going to right-click
and search for velocity. And if we scroll down, we should find the
velocity option. Then we need our
current rotation. So let's do that. We're going to right-click
and do gap character and use the gap
character variable. Drag out from that
and do get rotation. And we'll use the
gets active rotation. Then we're going
to right-click and search for calculate direction. And this is a function
that's actually built into all Animation Blueprint,
which is really handy. It just allows us to
plug in our velocity. Rotation and that gives
us our direction that we can just plug straight
in to our set note here. Now we can head back
to our Anim graph, then to the locomotion. And then two are aimed movement. And we can grab that
direction variable, plug that into our node here. So now we can compile and we can try this
out. So we'll hit Play. If I left mouse, you
can see that we're aiming correctly and
if I start moving, we're actually playing on
new aimed walk animations. If I left-click while moving, we transition back to our
normal running animations. Now if yours isn't working, you can go back to the locomotion
state machine and just make sure that all of the rules that you've set up our correct. So they look like mine do
right now. The one down here. And make sure that in
movement checks you do have aimed
movement ticked on. Now currently our character isn't actually using our left, right or backwards animations. And that's because
of a setting we have turned on in the
Character Blueprint. So we're gonna go to the
third person folder, blueprints, Then
ThirdPersonCharacter, and inherit. We're going to select the
Character Movement Component. Then we're going to scroll
down to the rotation settings and we're going to untick
orientate rotation to movement. And this stops our character facing the direction
that we're moving in. Now we can test our animations, will compile and hit Play. And now when I
moved to the right, you can see we plow
right animations, left or left animations, and then backwards or
backwards animations play. Now you may notice if you left-click and we start
moving to the side, our character doesn't actually
move to the side anymore. He's just moving forward. Now the reason that's happening is in our animation blueprint. The walk slash run state is
only using a 1D blend space, so it doesn't have
a direction input. All it has is a speed input. And that's why the
third-person character has on by default, the Oriente rotation
to movement. Now, there are a few
more settings in the animation blend space
that I wanted to show you. So we've got the
grid divisions now, this controls how many
spaces we have on our grid. So if I increase this to say, eight to eight here as
well on our vertical axis, you see that we now have
more blocks on our grid. This is helpful for
if you're using the snap to grid turned on. And this just gives you more
points on the grid to snap to say if you wanted an
animation in a specific place, you can increase these values
to get a snap point there. Then we've got the
smoothing time. Now this is how
long it takes for an animation to transition
to another animation. If we were to set
this really high, say five seconds, for example. Now when we hit play and
I moved to the right, you'll see that it takes five
seconds for me to actually transition into our
move right animation. So usually you'd want to use
smaller values for this. Say, for example, 0.250.25
down here as well, just to give a little bit of transition time between
moving between animations. But by default
these are set to 0, so the animation
is just transition instantly to each other. So we can just set
those to 0 for now. There's also some settings inside our Animation Blueprint. So if we had that, then we'll go to locomotion, aimed movement. And if we select this node
and scroll to the bottom, you can see there's a few
additional settings here. We've got the play rape. So this is how fast
the animations in our blend space will play. One is normal speed, two would be twice normal speed. Next is loop. Usually you want this
left on for blend spaces, but if you ever want
to turn this off, you can turn that off here. We also have the start position. So if you wanted
the animations to start at different
time other than 0, you can change that here. Then lastly, we've got
our blend space setting. This is how we change
which button space we're actually using on this node. So that's it for this lesson, but we will be using blend
spaces in our future lessons.
51. Animation Blueprints (Aim Offsets): Hey everyone. In this lesson
we're going to take a look into aim offsets. Now, aim of sets allow
us to actually have our character look in
a specific direction. This can be helpful for if you have a weapon and
you actually want the character to look in the direction that your
camera is pointing. Now, aim of sets actually work very similar to blend spaces. We have a graph that we
can place animations in, and then we use two
variables control which animations
we want to play. Now let's do this. We're
going to need some animation, so I'm going to X out of
playing NetTutor here, I'm gonna be using some
animations that are included with the lesson
Animations folder. If you don't have this
in your projects, I show how to add these in the beginning of
the montage lesson. So if you go take
a look at that, that will explain
how you can get these animations
into your project. Now if we scroll
down to the bottom, we'll find the EO animations. Now this stands for AIM offset, and you can see that we
have quite a few of them. And these are animations for each direction that the
character can be facing. If we open up this down facing animation
here, for example, you can see that it's a
single frame animation, meaning it doesn't actually
animate the character, is just a single frame of
our character looking down. Then if we close this
and go to another one, say our animation here. This is an animation
that's just single frame, but our character
is looking left. Now, using our aim offset, we're going to recombine all of these animations
and then control which one we want
to play depending on the two variable inputs. And those inputs are gonna be the rotation from our camera. And that will allow
us to control which direction our characters
facing using our camera. To start with, we
will close this and we're going to create
a new AME offset. I'm gonna do this inside the
mannequins, then animations. So we'll click the
Add button here, then head over to
animation and you want to find a more offset now, similar to the blend spaces, that is a 1D option which allows you to control the aim of
sets with just one variable, but we're gonna be using
just the normal aim offset, so it will create one of those. And now we need to
select our skeleton. I'm going to select
the skeleton that comes with the third
person template. So that's this one here in
CSS path mannequins meshes. So we know that's the right one. That's going to create
a new A-Master. So I'm just going to
call this aimed A0. So we know this is the
aimed at animation offset. And then we'll open that up. I'm just going to drag mine
up to the top bar here. So now we're inside
our aim offset. You can see it looks very
similar to a blend space. We have our graph down here. We have the same horizontal and vertical axis settings here, and we get our preview
at the top here. So to get started, we
need to set our graph up by naming our
variables down here. So our top one for
horizontal, we want York. We're going to set
the minimum five, U2 minus 90, and the maximum
value to positive 90. So that'll give our character
the ability to play an animation when
we're looking all the way right and all the way left. Then we do the same for pitch. So we're going to name
our vertical axis pitch. And the minimum value
will be minus 90, and the maximum value
will be positive 90. And this means that we'll
be able to set an animation for all the way up and
all the way looking down. Next slide, our blend space is, I'd like to take on
the snap to grid option here and also down here, just so when we drag our
animations and we know that they are snapping
to exact values. Now before we start adding
animations to our aim offset, I just wanted to
explain a little bit about what it actually does. Now, aim of sets use
additive animations, which means the animations
that we play using our aim offset don't replace
the current animation is being played
on the character. They actually add to
those animations. This means that we can have our aim offset playing
with our character, looking in a direction
while still also playing, say, an idle animation for
the character breathing. But for us to do this, we actually need to
change the animation. So we're gonna be
using an offset into additive animations. Now, we have to do this anyway because we won't
actually be able to place those animations in here until they're set
up as additive. And I can show you that if we
scroll down to the bottom, we should find our A0
animations down here. If I try and drag one in, you'll see it won't
actually let me, and it says invalid
additive animation type. That's because currently all of our A0 animations here
are not additive yet. We need to go into
them and change them to use additive settings. So there's a couple of
ways we can do this. I'm going to show
you how to change these settings in one animation. And then we're
actually going to use the matrix editor to change all of them to the
same settings. It will start with
the top one here. This is the A0, C, C. So this is our center animation. I'm just going to double-click
that to open it up. Now, in our asset details, we're going to scroll
down until we find the additive settings here. And currently you can see
it's set to no additive, which means this is just
a normal animation, not set up as an
additive animation yet. Now, for AIM offsets, we actually need to change
this to the mesh space, which means that this animation will calculate the changes. So that should be made
to the character and the mesh space instead of the local space for AIM offsets, you always want to use MSS space because that's the
only one it supports. Then we're going to change
the base pose type to the selected animation
scaled here like that. Now this allows us to set an animation that
we consider to be the default starting point
for this additive animation. So for this animation, we're in the center, and that's the actual one we want
to use as its reference. So we're actually
going to set this to the animation that
we're inside right now. We'll search for
CC and we'll use the MM rifle idle hip, FAI, AOC. See, this is just our center
single frame animation. Now, that's the animation we're actually going to use for all of our aim off set
animations here, because that's the center
point and that's where we want our additive
animations to add onto. So now we've set
this animation up as additive and we will be able to add this to our
aim offset now, but we still have
to do this for all of these animations down here. Now we could go
through each one at a time and set these
settings up the same, but there's a quicker
way to do this. So what we'll do is save and go over to the lesson
animation folder. We'll scroll down
to near the bottom, and we're just going to
select all of our aim offset animations apart
from our center one because we already
just set that up so we'll hold control
and select all of these here and keep going down
until we've got all of them. Then we'll right-click and we want to go to asset actions, then to bulk edit
via property matrix. And that will open
up this window here. Now if you haven't
used this tool before, it basically allows you to
select multiple assets in the Content Browser and change all of their settings
at the same time. So to do this, I'm just going to click on the assets
and do Control a, and that'll select all
of our assets here. Then in the property editor, you can see that we've
got the same settings we had when we were
inside the animation. We're just going to scroll
down to the bottom here. We want to find the
additive settings. So we're going to change
this from no additive to the mesh space
like we did before. Then we'll change this to
selected animation scaled. Then we want to select the
animation and weekend. We want to set this
to the CC animation for our aim offset,
so we'll select that. And now we can close this and all of our animations will
now be using those settings. So if we pick one at random
like our left down here, you can see if I scroll down, we find the additive settings. You can see that there
are now set up for us. So now all of our aim
offset animations are set up as additive. We can go back to
our aim offset. So I'm just going to close
these two animations for now. And we'll go to the mannequins than the Animations folder
and open up our aimed. I'm just going to drag
this up to the top again. So the last thing that we need to do before we start adding animations to our aim offset
is set a preview animation. And this just gives us
an animation that will preview on top of our aim offset so we can see
what it looks like. So it will scroll down
to the bottom here. Now for the preview base pose, we don't want to use
an additive animation, otherwise, we just
won't see a preview. So we're going to
search for idle. And we'll find the, I'm going to use the
rifle idle hip FAI here because our aim
offsets are actually for the hip fast, so
we'll select that. Then. I'm just going to save
and then close and reopen our aim offset like that. Now we're ready to start adding animations to our
graph down here. In the search bar, I'm
going to search for the center animation because that's the animation
that we want to use. When are your pitch is 0, because that's gonna
be the center point. I'm going to search for CC and we're going to drag it
into the center like that. Now you might get this issue where the preview disappears. There seems to be a bug if you scroll down
and we just reset the value for our preview and then we select, say a
different animation. We'll just search
for idle again. I'll select MFA idle, and then I'll search
for idle again. We'll select our
rifle, idle hip, FAI, like we did before and you
can see now it's working. I don't know why that happens. I think it is an engine bugs, so hopefully it gets fixed soon. Next we need to add
any other animations. So over here in the search bar, I'm going to search for CU, and that stands for Center up. So we're going to add that
animation up here because we want that for our characters
centered in the your butt, it's 90 in the pitch. So I'll add that here. You can see our previews
broken again, that's fine. We'll fix it once we've
finished adding or animations. And so we'll do another search and we're
going to search for c, d. And that stands
for Center down. So we'll add that to the
center at the bottom here. And again, this is for when R is 0 and our pitches minus 90. Next we'll do the
left hand side. So I'll search for L, C, that stands for left center. So we'll add that over here. This will be for our
pitch, or sorry, are you're being minus 90
and our pitch being 0. Then we want left up, so LU, and we'll add this
the top up here, then Aldi and add
that to the bottom. Then we'll do the
right-hand side. So we'll do LC, RC, That's right center
than we want. Right up. And that's that one down hit add up to the top
right hand corner. And then we want our D, which is right down,
and we'll add that to the bottom right
hand corner like that. And now we can save this. Next, we can fix our preview, so we'll do what we did before, which reset the value. Then we'll search for idle. I'll set this to
our idle animation, and then we'll search
for idle again. And we'll use the hip
fire ideal like that. Now this bug won't affect how our aim offset works in game. It's just a preview issue, so don't worry too
much about that. But now we can actually
test this out. So we hold control and move our mouse around and you
can see our characters now using those aim offsets
that we've just set up. You can also see that our idle animation is still playing, even though we're
adding on top of that animation our aim offset. And this is how additive
animations work. They add the
additional information to the currently
playing animation. Now we're ready to
actually set this up inside Art Animation Blueprint. So what we'll do is save
this and exit out of that. So it will open
up with the money Animation Blueprint and we
wanna go to the Event Graph. So if you're not there,
you can just double-click that and will enter
the event graph. And we're going to need
two new variables. So we're going to need a
variable for our pitch and yaw. So we'll add a new variable, I'm going to call this pitch. And we want this to be a float. So we're going to change
that to float type. And we'll do the same for
your super cool issue. And it's already set
to a float for us. So then we can just compile. Next, we need some code to
actually set these variables. So it will go down here and we're going to start
with the character. So get character. And we want them to get
character variable. And we need to get
the control rotation. So do get controlled rotation. And this is the
rotation of our camera. And then we want our
characters rotation, so do get actor
rotation like that. Then from our control rotation drag out and we're going
to search for Delta. We want the Delta rotate a note, and we want to plug b into
our axis rotation like that. Now, the delta node basically
just gets the difference between our control rotation
and our axis rotation. And this is the
direction we want our character to actually face. Now from the return value, we're going to search
for our intercept. And we want our interp2. And we want this to be
the target because that's the target direction we want
our character looking at. And then for current,
we're going to use our pitch on your values. Now, we can right-click and do split struck pen like that. We can plug the
values indirectly. Or if you recombine these, we can drag out and do make and use a make rotator
node like that. We can plug those
into here as well. So I'm gonna get the your, plug that into the your
input and then pitch, plug that into the pitch
and put like that. Then for delta time, we want to use the world's deltas time. So we're just going to drag
out and search for world. And we want get world
Delta settings. And then for internet speed, this is how quickly the value, returned value will transition from current to the target. So the higher this
is, the faster a or B, I'm going to set mine to 20. We can come back and
adjust that if we want to. Next, we need to clamp
the pitch and yaw angles. So to do that, we're going
to drag out and do break. Rotator from our pitch will drag out and
search for clamp. We want clamp angle. Now the reason we're
doing this is if you remember in our aim offset, we have a minimum value of minus 90 and a positive value of 90. We don't want our
pitch or you're going above or
below those values. So for them, we're
going to set minus 90 for the max we want 90. And then we'll copy
and paste this and plug the angle degrees into the Z or the
output here like that. Now we're going to use
these to set our variables. So for the top one, for pitch, we want to set pitch. And when we use our
set pitch node, and then for the bottom one, we want set your will use
the set your node like that. Connect these together. And then we're going
to connect these up to our sequences. So add a new pen, drag out from that and
connect that up to our pitch. Just going to double-click
it to add a root node. And we'll just drag that along here just to keep
things tidy like that. So now we're actually
ready to add our aim offset to
our Anim graph. So we'll head over there now. We only want our aim offset to affect the top half of our body, not the bottom half because
of effects the bottom half, it'll mess up our
movement animations. Now if you remember from
our blend nodes lesson, we set up a blend per bone
note here that will separate our lower and upper
body and allows us to have animations only
play on the top half. And that's what we're doing
here with our montage slot. So we're going to add our aim, the offset to this
code here because that's gonna be the code that's
played for the top half. So we're going to drag this out just to make a bit more space. Now I am going to
have my aim offset played before my Montage slot. The reason we do this is
if we play a montage, I don't want it to, or I don't want our aim offset
to affect the montage. So if we do it before, then when we do play a montage, it will overwrite our aim offset from our
mainstay cashier. We're going to drag out
and search for AIM offset. And we want the
aim offset plane. So we'll just create
that like that. Now we need to set which aim off set we actually want to use. And this is the same as
setting blend spaces. So over here on
the Details panel with the notes selected,
we'll scroll down. You can see it's actually
says blend space, but it's meant saying offset. But we can click
this and you can see are aimed A0 is there. So we'll select that. Just as a side
note, it might say a offset for you
if Epic fix this. So for me it says
blend space for you. It might say a offset, but you can just set your
aim offset here anyway. Then you can see
our notice updated. We've got our your
own pitch inputs, so we'll grab those
variables and plug those into our aim offset node. So we'll grab your pitch and plug that into
pitch like that. And now we can compile
and test this out. So we'll head over to
our level press Play. You can see that now when I am and I look about our character actually looks in the
direction my camera is facing. If we start moving around, you can see that our
blend space is still working with our character's
movement animations, while also our aim
offsets working. And if you look closely or idle animation is still playing, even though we're aiming in a different direction
with our aim of SAP. But now if I exit out of my aiming view just
by left clicking, you can see that my
normal animation for not holding a weapon
is kind of weird. And that's because we're
playing that aimed offset. Even when we're not aiming, we can change this in our animation blueprint pretty easily, so we'll
head over there. Now, in here you can see that our aim offset has
an Alpha value. Now, one means that
the aim offset is turned on and
0 means it's off. So if it's 0.5, it would take half the influence
of our aim offset. Now we can actually
change this to a Boolean to just
turn it on or off. So we'll select our note it, go over to the Alpha
value in C Alpha value, sorry, alpha input type is
currently set to float value. But if I change this
to Boolean value and see that now we've got
this total enabled tick box. And now we can just
grab bar is eight. Plug that into the enabled here. And now when we compile
and we hit Play, you can see now I'm not aimed. You'll see are, idle animation
is behaving correctly. But when I start aiming,
you can see that our aim offset then
begins working again. Now there is another
way that we can turn on and off our aim offset. So if we exit out of here and go back to our Animation Blueprint, instead of just turning on or
off this node specifically, we could actually have
a whole section of code run only when
is aimed as true. So to do that, we can
search for Blend tool, and we can use
blend poses Bible. And we use this in our
blend nodes lesson. So if you remember,
we can take this, plug this into our
default slot here, and then we'll take
disconnect heart is aimed. Plug this into the active value. So if it's aimed as true than the true
code here will run. And if it's false, then the folks code will run. So when we ain't, we want
our aimed codes rump. So we'll connect
this up to true. I'm going to click
on Enable tests. So it's always enabled. If we're not aimed,
we can just copy paste our main states cash. Plug that in here. This will work exactly the
same as it did before. So we can compile hit Play. You'll see when I
aim our characters doing our aim or
separate filename, you can see our animation
is working correctly. So as you can see,
both ways work. Which one you use, It's
completely up to you. This way can be a little
bit easier if you had, say, other nodes that you want it to run when it is aimed as true, because you could
just connect those up to here and have them run. When is this true? So that's it for this lesson. Hopefully you now understand
how you can set up a name offset and how you can use
them in your projects.
52. Animation Blueprints (Curves & Metadata): Hey everyone. In this lesson we're
going to take a look at animation curves and metadata. Now essentially,
curves and metadata allow us to add
additional information to our animations that
we can then read inside our animation
blueprint when they play. So to get started,
I'll show you how we actually create a new curve. So we'll go to an animation. I'm going to choose the
run forward animation. So for us that's gonna be in the Quinn folder
then under the r14. And the reason it's in
the Quinn folder and not the money is
if you remember, our character
blueprint is actually using the Quinn
Animation Blueprint. And in that we have the
Run 4D animation set. We'll open that up. And in here you can see
we've got a curves timeline. Now to add a new curve, you can just click the drop-down here and we can go to AD curve. Now as you can see, the
third person template comes with a bunch
of curves built-in. These don't actually
do anything by default until we use them
and actually set them up. But for now we're just going
to create our own curves. So we're gonna go up to Create curve, and we're
going to name it. I'm going to call mine
example curve like that. And you see that
that's now added our example curve
to our animation. Now this curve allows
our animation to output a value depending on what time
in the animation we're at. So currently you can
see it's just set to 0. So when we play this animation, all our curve is gonna
do is output a 0 value. But we can actually edit
this curve to output a different value depending on what point of the animation
that's currently playing. To do that, we'll head
over to the curve drop-down for the example curve, then we want to
select Edit curve. And if you remember from
our timelines lesson, this actually works a
lot similar to that. So currently, this
value is just gonna be 0 the entire time the
animations playing, but we can add in new points. So if I middle mouse click that adds in a new point for us. And then up here at the top,
we've got the time that that point is currently
at and its value. So if I set this to 0 or 0 is currently at 0
time and has 0 value. Now if I add another point, say at one seconds. So about here, we'll
middle mouse-click. Now with that selected, you can see the time is one and we can set the value to something else like ten, for example, you can see my point
is gone off the graph, but if we click this
little box here, it will actually bring all of
our points back into view. Now when this animation plays at 0 times the value will be 0. But as time moves on, the value will increase
along this line until we get to 1 second
and it will be ten. Then as the time
increases again, the value will stay
ten because we haven't got any
additional points. So now we can read
this value inside our animation
blueprint by going to the third-person map here. Then we want to go to
our Animation Blueprint. So animations then go to the
money Animation Blueprint. And in the event graph, we're going to add a new node. We're going to right-click
and search for curve. We're going to use
get curved valley. You can see we can
put a curve name. So this needs to be the exact name we're
using for our curves. So this is example curve spelled exactly the same with the capital
letters as well. Now, if an animation plays that uses that curve
that we've set up, this will output
is current value. So we'll add a new pen and just add in a print
string for example. And we'll plug the return
value into our print string. And we'll compile. And we can test this
out. So we'll hit play. And you can see
currently no animations that use that curve are running. So our value is just 0. But if I start running forward, you can see our value
increases to ten. Now it's resetting back to 0 every time the
animation loops. Because if you remember at
the start of our animation, it's 0, then it goes to ten. And then once it reaches the end of our animation
is going to loop. It will start again back at
0 and r value will be 0. Now again, similar
to our timeline, we can highlight
these points here. We can change how they
transition from each other. So up here we can choose which types of fall off will
be for the point. For example, we can select the automatic and you see now we get more of a curved effect
to our value increase. And we can use these
little handles to actually adjust how
our line changes. We can also move our points just by selecting them and
dragging them around. Now, I've got both selected,
so it's moving both of them. But if I highlight
just the one here, you can see I can move that
point around to change what our value is gonna be at that specific point in time. If you ever want
to see that value, you can mouse over or
you can find that here. And then the time value is here. Now currently we are
in the curve editor, as you can see here. But if you want to get
back to the normal view, you can just click this
tab and that brings us back to the tab that
we normally see. Now if you ever want to get
back to the Curve Editor, say you've closed
it by accident, you can click curve
and just edit curve. That will bring us back here. If you want to remove a curve, you can just click
that and click Remove curve and
that will actually get rid of our curve for us. Now you can have multiple
curves and an animation. You can just hit the
curve and another curve, you can either create or reuse one of the curves
that are in here. Now we can add this same
curve to other animation. So if we head out and we'll
go to the money and open up, say the jump animation. We could have that same
curve to here as well. We can go to AD curve. And instead of
creating a new curve, we can just search for the name. So we'll search for example. And you can see our example
curve is already there because we've created
it already exists. So we can reuse it,
will create that. And you can see it starts off with the default values of 0. Now, maybe in this
animation we want a dark curve to have
totally different values. So for example, we could middle mouse-click,
set this to 0. We could set the
starting value to something like minus 100. And we'll click the little box just to bring it
back into our view. Then we can middle
mouse click at, say, 2.5th and have this
value go to 500. And we'll collect
the box again just to bring out both into our view. And now when this
animation plays or output totally different
values from our curve. So in test this out, hit play
and see if I run forward that's still playing our
curve from that animation. But if I jump,
you'll see it goes up two completely
different values. Next we have metadata, which is basically a curve
that's just got a one value. So it show you what I mean
we can add to the jump here and we'll go back
to the tab up here. Now we can remove this
example curve for now. So we'll just do remove curve, go up to curves and you can
see we've got metadata. Now in here you can see, again, there's a lot of
default ones that come with the third
person template. But if we search, for example, curve again, you'll see
that that's there as well. Even though it is a curve, it's also just metadata as well. So we can search
for curve and we can add our example
curve like that. Now as you can see, its
default value is one. And if we go to the
curve dropdown, there's no option to edit this. Now that's because
metadata kind of acts like adding a Boolean
to your animation. If it's added to the animation than the Boolean is the
equivalent of being true. And if it's not in the
animation, then it's false. In our animation blueprint, this return value will
either be one or 0, depending on if
the animation has this metadata with this name. Now when we hit Play,
you'll see when I jump increases to one and then
decreases back down to 0. Now animation curves are used for all sorts
of things like controlling facial animations or properties inside of materials. We're not going to
be covering that in this lesson purely because it's a little bit more advanced. But what we can also do
with animation curves is read them inside our
Animation Blueprint, like we've been doing with
our curves on metadata. An example of what you could
do with curves in the future is maybe you have a project
that has shooting in, but certain animations you don't want the player
to be able to shoot. Well, you could create
a block shooting curve. That's the animations that you
want to block shooting in. Then inside your
animation blueprint, you could read that curve. And if the value is above 0, you know that you should
block shooting in your code. Now one thing to
keep in mind is if we head back to our
jump animation, because we've got
our example curve here added as metadata. We can't then go and add example curve as
a curve as well. If we had to add curve, we searched for example, in C, It's not going to show up until we delete
this example curve. So we'll remove
that, then go to Add curve search for example. Now, you can see that it's showing up and we can
add it as a curve. Now, if you want to
find out where all of these curves are actually
set and you can manage them, rename them, or delete them. We'll head over to
the Content Browser. Then we're gonna go to
the mannequin folder, then meshes and we're going
to open up SK mannequin. Now this is our
characters skeleton. And over here you can
find the anime curves. If yours isn't open,
you can go up to window and select on
anime curves here. Now, over in the
anime curves as well, we can delete curves so you can right-click column, hit Delete. You can rename them, or
you can add new curves just by selecting Add new
curve and enter in a name. Now, lastly, if we try to
add our example curve to the lesson animations over here and the lesson animation folder. We won't actually be able
to find our example curves. So if we open up, say
the rifle, walk forward, I go to curves and I go AD curve and I
searched for example, see that it doesn't
actually show up. Now if you remember
these animations in our lesson Animations folder or using a different skeleton, them from our character. So we actually have to
manually add our curve to this skeleton for these
animations to find it. So to do that, we'll just
go to mannequin than two meshes then to SK mannequin. And in here we'll
go to anime curves, which is going to
right-click add a curve. I'm going to call
this example curve exactly the same as the name
we gave our curve before. We'll hit Enter,
and now we've added that curve to our skeleton. So now we can close this
and head back to our rifle, walk forward, then two curves. And we can either add a curve or metadata, and we can search, for example, and we can
find our curve now. So I'm just going to
add our example curve. I'll edit it to add some values. Will middle mouse-click word and a value at say 0 for ten. And then we'll
recenter the graph. I don't have a value, say
one for 500, like that. We'll recenter it just to make sure everything is correct. Now we can test this out. I'll hit play and I'll
aim and walk forward. And you see our value is
increasing that like that. Now if yours doesn't and it just keeps reading 0 when
you walk forward, try just saving everything
from restarting the engine. This is a bug at the moment
with compatible skeletons. If you remember, that's why our character can play the
animations from our lessons. We saw pay compatible skeleton
in the montages lesson, but it's a little bit buggy
as it is a new feature. So sometimes you
just need to save and reopen the project and
it should work correctly, then that's it for this lesson. Hopefully now you understand how to add metadata and curves to animations and then read those values inside and
Animation Blueprint.
53. Gameplay Systems (Interaction): Hey everyone. In this
section of the course, we're gonna be using everything
that we've learned in our previous lessons to create some common
gameplay mechanics. Now, in this lesson, we're
going to be creating a basic interaction system. This will allow us to
run code inside of other objects when our
player interacts with them. Now for those of
you that have been following along in
previous lessons, I have created a new
third person template just so we've got a fresh start for this section of the course. So to get started,
we're gonna go into the ThirdPersonCharacter
Blueprint and that's just inside the third-person
folder, then blueprints. So it will open that up. And inhale, we're
going to create a new function and
we're going to call that look at actor will compile. Now this is a function
that's actually going to detect which actor we're
currently looking at. And to do that, we're
going to use a line trace, so it will drag out and
we'll search for line trace. And we want line
trace by channel. If you remember from
our line traces lesson, a line trace allows us to detect objects between the
start and end locations. So this makes it
ideal for things like an interaction system
because we can detect, is the player currently
looking at an object. So to do that, we're going to need a
little bit of math to determine where our line
tray should start and end. So we're going to
right-click and do get control rotation. And that gives us
the current rotation of our players camera. From that, we want to get
the forward direction. So we want to search for
get rotation x vector. Then we want to drag
out from that and do a times or multiply node. And we're going to change
the input here to a float. So we're just going to right-click do
convert pen and then select the flow and we
want double-precision. So we'll do that. It's going to move these
back a little bit. Now, the value we
set here is how far from the start location our
character can interact. So say I wanted
It's interacts and distance to be four meters. I'm going to put 400 here and we will be able
to change this later, but for now, we'll just
leave this at 400. Now we need a start location
for our line trace. Now we could just use the
characters actor location, but if we go to Viewport, characters acts or location
will be in the center. And I would rather have my
line trace come from the head. So we'll head back
to look at actor and we're gonna get our
head bones location. So to do that, we can grab the mesh component from
the Components panel, Drag out and search will
get socket location. We can use this node with
both socket names and bone names and it will give us the location of that
socket or bone. I'm going to put the head bone naming which just
just head like that. And I'll just move
this back a bit. Then we'll plug the
return value into the stock because
that's where I live. Trace is going to
be starting from. Then we're going to
need an odd node. So we'll drag out
from return value, do I add node? And we're going to
add the output value of r times note it to the Add Node from the app node two and
input on our line trace. So just to explain, our line trace is
going to start at the head bone location and then the end of our line
trace is going to be again at the headphone location, but we're adding four meters in the direction that
our camera is facing. So now we can test this out. We'll set the Draw Debug
Type two for one frame, so the line trace will be
visible for one frame. And then we actually need
to run this function. So we'll just head
to the Event Graph, Right-click and search for tech. And we'll add an event tech, which is going to
do this temporarily to test everything's working. Then we'll grab
the lookout actor and connect that to
here and compile. Now we can test this
out so we'll hit play. And it's kind of
difficult to see the line trace because
our heads in the way. If we press F8 to reject our
mouse it and we move around, you can see that
the line trace is starting our head and he's going four meters forward in the direction our
camera is pointing. So next we want to store what the line trace
is actually hitting. So we'll exit out
of planets to here, go back to our
ThirdPersonCharacter, and then back into our
lookup actor function. And we'll move along
here to the end. Now we want to add
a new variable that stores are hit result
from our line trace. So we'll just drag out from out here and do promote to variable. And we'll name this, look
at hit result like that. Now, we can use that
variable later on to detect what our character
is currently looking at. Now I'm also going
to create a variable for this 400 value here. So we'll drag out and do
again promotes variable. And that will just
create a float for us. And I'm going to call
this interact distance. Now, we'll do this
just so we can easily change our Interact distance
for our line trace. So you can see that it's
actually just set itself to 400. And if we wanted to later on, we could adjust this in
the class settings here. So instead of having to go into function to
change the distance, we can just go into here
and change it easily. And to keep things organized, we could give it a
category as well, so I'll select it and
we're going to change the category name to
interaction like that. You see now it's got a
little interaction category that we can keep all
of those variables. And if we go to class defaults, we should have a interaction
category, if we can pump, will compile first, then go to class defaults and
you'll see we've got now an interaction category and our interaction distance
variables in there. Next, we're going to change
our lookout actor to run on a timer instead
of doing it on tech. And if you remember, on tech
will run every single frame. So if you're getting, say, 200 frames a second, this will be running 200 times. Which is a little bit excessive
for our locker actor. So instead we're
going to use a timer. So I'm just going to
get the begin planet. From that, we'll drag out and
do func function by timer. We want set timer
by function name. Now we can delete our
local actor here. And this allows us to have a function run at
a certain time. So we'll set that function
name to look at AXA. Now the name needs to be spelled exactly the same with capitals, otherwise this won't work. Then we're going to
take on looping. Then we're going to
set the time to 0.03. Now this means that our
lookout actor function will run 30 times a second. Now that might seem like a lot, but for a single trace,
it isn't a big deal. And it means that when we are looking around with our camera, we get the most
up-to-date information. Now, another thing
we can do is store this return value and
that's our timer handle, just in case we ever
want to stop this timer, maybe for our character dies. We don't want the lookout act
to trace running anymore, so we can use the timer
handler to stop it. So we'll just drag out
to promote the variable, and we'll just call this
look actor timer like that. So now if we ever
wanted to stop it, we can use that
variable to do that. So now we've got our look
at active functional setup. We need to now add a new
interface that we can add two other blueprints
to actually run events and code when they
get interacted with. So what we'll do is
we'll just compile and save this and go to
the Content Browser. And we'll right-click
and we're going to add a new Blueprint Interface. So we'll go to blueprints
and then we want the Blueprint Interface here, and we're
going to name this, I'm going to call
mine BP underscore interaction,
interface like that. And we'll open it up. And I'm just going to add
mine to the top bar here. Now if you remember from
our interface video, we don't actually do
any coding in here. All we do is add new functions and give them
inputs and outputs. We've already got a new function that starts with the interface. So we'll just right-click
and rename this. I'm going to call mine
interact like that. And we'll compile and we
can add new inputs now. And this is information that
we're going to send from our player character blueprint to whatever blueprint
we're interacting with. So what I like to do is add a character reference
just so we can access information from
the character that interacted with the blueprint that we're running this code. So we'll search for character, will use the character
type object reference. I'm just going to
name this character. Now of course in the future, if you wanted to send
them information from the character to the blueprint
it's interacting with. You could add new inputs here. So now we have our
function that will run whenever our player
interacts with a blueprint, but we can add some
additional functions as well. So I'm going to add
one. And we're going to call this allow interaction. And we're actually going to
add an output for this one. So we'll add a new output. And we'll set this
to be a Boolean, and we'll just name this
return value like that. So now this gives
us a new function that we can check before we run the Interact function just to make sure that the blueprint we're interacting with does have its interaction turned on. Now we're going to add
one more function. So we'll go to add function, and then we're going to
call this interaction name. Then we'll add a new output. And this is going
to be called name. And we're going to
set the variable type two texts like that,
and then we'll compile. Now this allows us to
set a custom name in any blueprint that we add our
interaction interface tube. And then we're going to add
a little bit of texts to our screen so that when our
player looks at an object, it's going to display
the name that we provide using this function. So now all of this has added. We can compile and save it. Now, heading back to the
third-person character, we need some input events to actually run our
interactive code. Now we could just
right-click and search for the temporary input events
that we've used before. But instead, we're
actually going to go to our project settings and
properly add an input. So we'll go to Edit
Project Settings. And in here we want to go
to the Input category. And now we want to add
an action mapping. So we'll go to Action Mappings. We'll click the Add
Action Mapping button. And we're going to call
this interact like that. Then we'll click the
keyboard and you can pick whatever your key one, I'm going to press E,
so that sets out to E. Now that's set up,
we'll head back to our character right-click
and search for interact. And we want the
interact underneath the action events here
to add our input. So now we're going
to add the code that actually tells
the object that we're looking at to run
its interaction interface. So to do that, we
go up the lookout, hit resolved, and we'll drag out from that
and we'll break it. And we'll click the little
down arrow here to get all of the variables or drag
out from Hit Actor. And we're going to
search for Interact. And we want the
Interact message here. Now I'm going to
click this arrow again just to make this smaller. And we can tie this
up a little bit. Now before we run this,
we will first want to check is the act of violet. So we'll do is valid. We'll connect this
up to pressed. And we also want to check
is allow interaction true. So we'll drag out again
and search for Allow. And we can use the
allow interaction pair. Plug that into is valid. And then we want to
run a branch node. So we'll drag out from the
return value and do IF. And then from that, if our return value is true and
allow interaction is true, we want to run our Interact so we can plug it in like that. Then for our character
input because we're inside our
ThirdPersonCharacter, we can just drag
out and do self. And that will pass
a reference to this character through
the Interact function. Now let's keep things tidy. We can actually
highlight all of these. Note it, not the input event, just the code that
we've got highlighted right-click and we can
do collapsed function. And I'm just going to call
this interact like that. We can just move this here. Now, all of that code is just inside our new
interact function. So if we double-click that,
you can see that here. We can just move this up
here, so it's a bit tidy. Now we need to set
up an actor that our character can
actually interact with. So it will compile and will
go to the Content Browser, just going to create a
new blueprint class. We'll set it to an actor. I'm just going to call this BP underscore interaction example. Like that. We'll open it up and we'll
add a new component. I'm just going to add
a cube component. Like that. Just gives us something that the
line trace can hit. But you could use
a skeletal mesh or a static mesh component and have a custom measure
if you wanted to. Now one thing to keep
in mind is if you use a static mesh
or Skeletal Mesh, it must have
collision because if it doesn't align,
trace won't hit it. So to check if your static
mesh has collision, you can just go to its stack
mesh in the Content Browser. So for example, what are Coupa? We can just click the Browse to and content browser to go there. We can open this up. Now in here, you can go to show and then go down to where
it says simple collision. And then if when
you take that on, you get this light green outline here, that means
you're all good. It has collision. If you don't have that, you can go up to the collision
drop-down here, and you can try these
different options to add some collision
to your object. So we're using this
cube so we know it does have simple collision,
so we're all good. We can add back to our
interaction example blueprint. Now in here we need to add
our interaction interface. So we'll go to Class
Settings then to implement it interfaces,
and we'll add a new one. We're going to search
for interaction. And we want the BP
interaction interface. And then we'll compile. Now, if we go to our
My Blueprint panel, click the drop-down
for interfaces, you can see that
we've got all of our new interface
functions that we add inside our interaction
interface. Now you may notice that this one is yellow, but
these ones are great. Now that's because
if you remember, our Interact doesn't actually
have a return value. If I click this, it will just create an event on
our Event Graph. But if I click or
allow interaction, for example, if you remember that did have a return value. So it opens this up
in a function editor. So that's the main difference or interact doesn't actually
have a return value. If you remember
inside the interface, if we select our Interact, you see it has no outputs, but both of our other
ones do have outputs. And that's why they're
different colors. And if we click interact,
it creates an event. And if we click on
Allow interaction, it comes up with a function. So to get started, we just want to enable, allow interaction. So we're just going
to take this on. But in your future projects or function like this is
handy because you may have an object that you want
to be interactable some of the time and some of the
time you want to disable it. So you could just return
a different value when you want to disable
its interaction. Next we have the
interaction name, so we'll just double-click
that to open it. Now we can just manually enter a name in here
if we wanted to, but I'm going to drag out and
promote it to a variable. So we'll do promotes a variable. I'm going to call my name
and leave it as texts. So then we'll compile and
I'm just going to add a default value such
as default. Name. Won't be able to
change this later on. So we'll just component. So now we can actually add some code to our event interact. So we'll head back
to our event graph. And now because we
double-clicked interact, it's actually just added
this to our event graph. But if we didn't have this, we could also right-click
search for event interact. And we could create
that this way as well. Now this is the event that will run when our character looks at this object and
press a-z soap. For now, we'll just drag
out and do a print string. We can print string the
name value for example, and just plug that in like that. Now the good thing
about this event is we have access to our
character blueprint. So maybe you had a component
on your character blueprint that was an inventory
or a health system. You can just drag out
from the character here. We could use get
component by class. And we could use
this to check does our character have a
specific component? If it does, then we can
use the return value to access any of that
components variables. Or we could just cost
to our character. So we could do cost to
ThirdPersonCharacter. And then using this, we could get variables or
functions from our character. So we could get, say, the interaction distance
if we wanted to for some reason or if you add
health variables, are. Whatever else, you could
use this to access those. But for now we're just going
to run our print string. So I'm going to delete
these and connect this backup to the
print string like that. Now one of the thing we wanna do is with our name variable. We just want to take
on instance editable. And if you're a member,
that just means that when we drag our
cube into our level, will be able to change this name for each
cube that we drag in. So now our interaction system is actually pretty much set up. But I did want to add
in a HUD that we'll say the actors interaction name whenever our player
looks at that actor. So to do that,
we'll just go back to the third-person folder here, then blueprints
and we're going to create a new HUD widget. So we'll right-click,
go to User Interface. We'll do a Widget Blueprint. I'm going to select
use a widget. And we'll call this BP
underscore HUD, like that. And we'll open it up. Now
because this is our main HUD. We're going to add
a canvas panels. So just search for
Canvas and we'll add that to our hierarchy here. Then I'm going to want some text actually displays the
interaction name. So we'll search for
text in here as well. And we'll add that
to our canvas panel. And we're going to have it
so it's up at the center. So I'm going to change the anchor for text
to center like that. And you can see our
position is messed up. So what we'll do is select
this to 000 like that. So now you can see
where centered. I actually want the center of the text to be in the
center of the text. So what we're gonna
do is do alignment, do 0.50.5 like that. So you can see that the
text is now centered. Now I want my text to
be a little bit higher, so I'm going to hold
Shift and drag up. And that will actually allow
me to move our texts and a direction and lock it to that direction so you can
see I can move it up. Say here. Now I'm going to change the font just to make
it a little bit smaller. So we'll make it say 20. And we'll compile. Now, you can spend
as long as you like setting this up so
the text looks nice. I'm just doing this quickly
so we can get it running. So first we need to hide our texts when we're not
actually looking at an object. So What we're gonna
do is we're going to use the visibility here. We're going to
create a new binds. So we'll do or click on
bind and do create binding. With that open, we need
to determine when we should set this text
visible and then hidden. So to do that,
we're going to need some variables from our
ThirdPersonCharacter. So we're going to need
a reference to that. So we'll start by going
to the Event Graph. We're going to delete this
node and this node here. We're going to get
the player character. And from that we want
to check is it valid? So do is valid. And we'll connect
this up to construct. Then we'll drag out again and do Cast to ThirdPersonCharacter. So we can then use the output of this to
store as a variable. So we'll do promotes variable. I'm just going to call
mine character like that. Then I'm actually going
to highlight these nodes. And we'll right-click and just
do collapsed to function. And we'll call this
set up references like that and actually
keeps things nice and tidy. And we can reuse
this later as well. So now we're ready to go back to our get visibility function. And we want to get
our character. And we just want to
make sure that this is valid before we run any code. It will connect this up to here. And if it's not valid,
then we can actually run our setup references like that. And we'll use this return
node, plug that in here. We'll just set this to hidden. So if our character isn't
valid when this runs, it will try and set the
character variable again. Now if the character variable is valid, we want to get it again. Then from that we want
to drag out and get look at hit result. We would drag out
and do a break. We will extend this node
and we want Hit Actor. We do is valid. And if it is valid will
make this smaller again. So we've got a bit more space, which tidy this up like that. So if this is valid, we then want to check is
it interactable? So we'll drag out and we'll do allow interaction like that. And if that is true, then we want to set our
visibility to visible. So we'll copy this and paste it here. So this too visible. We'll plug it in like that. So once you're done, it
should look a bit like this. Now there is
actually a couple of one or more nodes we need. So what we'll do is we'll
copy our return value, paste it here, and
we'll set it to hidden. Now, if allow
interaction is false, we want to hide our
texts, so we'll do that. And also if the hit
actor isn't valid, we also want to hide our texts, so we'll plug that in like that. So that covers setting
our texts visibility, but we also want
to change what it says to the interaction name. So what we'll do
is we'll actually copy this code because
there'll be the same. So we can copy all of
this and this as well. And so it makes sure you have all the nodes highlighted
here do Control C. Then we'll go to the designer, select our text here. And we want to go to the text and bind, then create binding. And in here we're going
to paste in those notes. And I'm gonna get the
beginning node connect up to r is valid like that. Now we need to return some sex. So this one would
just plug into here. And we don't want to
return any texts for this, so we'll just leave that empty. We'll copy this and
paste this over here. So now, once we know allow
interaction is true, we want to actually get
the interaction name. So we'll drag out from the
reactor do interaction name. And we'll connect
this up to true. Now, if the
interaction is false, we just want to return
an empty value. Let's do that. Then we'll copy and paste
this again, paste this here, and connect name up to the return value like
that. Then we can compile. And once this is done, it should look a bit like this. Now the last thing you
need to do is actually add our hard to play a screen. So to do that, we'll go to the ThirdPersonCharacter
Blueprint, that event graph. We're going to add this
to our Begin Play. We'll right-click and
do Create Widget. Connect this up to our notes. And owning Player, we'll just do Control, get
player controller. Like that. We need to set the class to
the hub that we just created. So BP HUD. Now, it's
always a good idea to store this return value when you're creating your main HUD. So we'll drag out
and we'll probably this to a variable,
we'll call this HUD. And that's just that if we
want to use it later on. And then from the output
of this set node, or just search for Add
to Viewport like that. And that will actually
add our widget to our players screen. So now we're ready
to test this out. We'll compile and
head to our map. We want to add some of our interaction examples
to the level. So I'll add one here
and one over here. And if you remember, because
we set our name to instance editable inside our
interactable example, we have that value here. So for this one, I'm
going to set this to say sword. For this one. Set it to be something
like pipe like that. So now we can hit play. And if we run over to this cube here you can see it's
printing out sword. And if I press C, you can see
it's printing out the name of our sword
interaction example, and it will do the same with
var pi example over here. Now we could spend a
little bit more time tidying up our HOD texts x, it's a little bit hard to see. So if we exit out and
open up our hood, we can select our texts
in the hierarchy here. And first we could
center it so our text nice and centered and we could
add a background as well. So what I'll do is
right-click do rap with, and we'll do rap with a border. And then for our
border, we'll select that and we're going to
set size to content, so it will resize to
the size of our text. We can change the color, so I'll change the brush
color to say a gray. So it's just a little bit
easier to see like that. And we could also
add some padding. So we'll select our text
and we'll set the padding, appear to say eight. So it gives us a little bit
of padding around the edges. And now we've added
a new widget. We actually need to set
its visibility as well. And we can reuse our
visibility function that we use for our texts. So we'll scroll down, go to the visibility
option here. We'll just click bind
and you can see that our visibility function from earlier is that we can set it. And now our text border
here will change their visibility whenever we're looking at an object
we can interact with. So we can test this out. We'll compile and head
back and hit play. And now we can see our text is centered
and it's a little bit easier to see because we've got our gray box when we're
not looking at something, you can see that our boxes
hidden along with our text. Now currently what we're
doing when we presi and selecting one of our interaction examples is printing out a name. But of course this
is just an example. You could change this
to whatever you like. So we can go to our
interaction at example here and have the actor say destroy
when we interact with it. So we could add Destroy Actor. Now, when we compile
it and hit Play, if I interact with
the cubes now, you can see that they
both get destroyed. So that's it for this lesson. Hopefully you now
understand how we can use Blueprint Interfaces to run
code in other blueprints, like for example, when we
need an interaction system. And in our next lessons, we're gonna be
adding more gameplay features to this project.
54. Gameplay Systems (Damage): Hey everyone. In this lesson we're
gonna be setting up a health system
and we're also going to be using
the damage system that's built into Unreal Engine. So to start with,
we could just add our health variables
and functions directly to our
third-person character. But instead we're going to
create a health component. And the reason we're
gonna do that is because we can
reuse it and other blueprints if we wanted to later on. So let's get started. We'll click the Add button
in our content browser, go to Blueprint class and we're going to select an
actor component. We're choosing act component instead of seeing
component because our health component doesn't
need to exist in the world. It just needs code, so we'll use active component. I'm going to name
mine BP underscore health component like that. Now we'll open this up and I'm going to drag mine up
to the top bar like that. So we'll start by creating
some health variables. So I'll add a new variable. I'm going to call this
current health like that. And I'm going to set
mine to an integer. You could use a float
if you wanted to. Personally, I prefer to use integers for health because
it's a whole number. So we'll start with current health and that's
gonna be an integer. Then we're going to
create another one. This is going to be
called starting health. And we want another one, and this will be
called max health. Then lastly, we want
another variable called and take damage. And we're going to
change this to a brilliant because
that's true or false. Then for these three variables, we're going to take
one instance editable. So we'll just do that now. That just means that when we add our health component
to another blueprint, when we select the
health component in their components panel will
be able to edit these values. So now we'll compile and we'll
set some starting value. So for starting health, I'm
going to set this to 100. For max healthful set
this to 100 as well and can take damage will take on as well,
and then compile. Next we're going to
create some functions are actually going to change
our health variable. So we'll add a new
function and we'll call this increase health. Like that. We'll add a new input and we'll call this increase amount. And we're going to set this
to an integer like that. And then we'll compile. The first thing we
wanna do is make sure our current health isn't going to be greater than r max health. So we get our current
health and we check is this less than r max self? So we'll get maps, health. And we only want to run this code if it's,
if this is true. So it will move
this down here and add this to our input
node like that. Next we want to check
will adding the amount, the increase amount
to our current health make her over r max health. So to do that, we'll get
current health will add our increased mountain now we could just drag out from here
and plug this in like that. Or we can drag out from here
and do get increase amount. And you can see we can
actually get that value from our input node without
having to create a variable. It just lets us use that here. And if that doesn't show up,
just make sure you can pull off divided the input and you
should be able to find it. Next we want to
check is this value less than or equal to max out. So it will get max health. And if it is, then we can set that amount
to our current health. So we'll do this and
then we can copy and paste these nodes
pasties over here. We'll do set current health. That. Then if false, which
means the increase and current health values are gonna be greater than r max. How often we just want to
copy and paste this and say, I'll help to max out like that. We could add a reroute note
here, just keep things tidy. So once you're finished, should look like this. So next we want a
decrease health function. So I'm going to search
for it, or I'm going to create a new
function and call this the grease, like that. And again, we're going
to add an input to this, so I'll make my
window bigger here. Why the new input, and we'll
call this decrease amount. And we'll set this to
an integer as well. And then we'll compile. Now, we want to
check is our current health greater than 0? So the current health
greater than 0. And if it is, then will allow or decrease health
to run like that. Next we want to check is our current health minus r decrease amount greater than 0. So we'll do get current health and we want to do
minus or subtract. We want to subtract
our decrease them out. Now again, we could
plug this in like that or we can drag out sexual get decrease amount
and we can add that here. And then we want to check,
is this greater than 0? If it is, then we can allow that amount to be decreased
from our current health. So we'll do this. We'll copy this,
paste this over here. We'll do set current health. And if the amount
is less than 0, we just want to set
our current health to 0 because we don't want
our health going below 0. So it will just add a note here, just tidy this up,
and once you're done, it should look like this. Now one thing I did forget
to add is we want to check can take damage before
we increase the health. So we'll drag this out further, which is going to grab
our can take damage. And if this is true, then we will allow
this function Trump. So it will just plug this
in here and true into here. Now we're also going to add some event dispatchers
and these can be helpful for if we add our health component to
different blueprints, we may want something different happened in one
blueprint than another when our health increases or decreases when the
health hits 0. So we'll start by creating
an event dispatcher. And I'm just going to call
this on health increase. Like that. We'll create another one
called on on health decrease. Then we want on health 0. Like that. We could add some inputs to our own health
increase and decrease. So we'll go to the Details panel here
and add a new input. I'm going to call
this increase amount. And we'll set it to an integer. And we'll do the same thing
for unhealthy decrease. So we'll add a new input and
we'll call this the crease. Spell correctly,
decrease amount. There we go. And we'll set
that to an integer as well. So inside or decrease
how function we can run our own
health decrease here. So we'll do cool. Plug this in here, and then we want to get a decreased amount. So I'm just going
to copy and paste this and plug that in here. Then for health 0, we
want the non-health 0. So we'll call that,
plug that in here. And we didn't add
an input for this, so we don't need to
plug anything else. And then we'll go to
our increase health. And over here, we want
unhealthy increase. We'll plug that in here. And we'll get the increase
amount like that. We'll plug in this up here as well because when we
set our max health, we will be increasing
it as well. And that will create
one more function. And I'm just going to call
this apply starting health. Then here what we're
gonna do is go our current health and set
this to our starting health. Then we'll run this function in our Event Graph on Begin Play. So we'll grab that
applies starting health and plug it
in here like that. And then we'll compile
and save this. Now we can go ahead and add our health component
to our character. So we'll head over to the
ThirdPersonCharacter Blueprint. Then I'll make this window a
little bit larger like that. And we're going to
add a new component or search for health. We'll add the BP health component
and then we'll compile. And with our health components selected in the Details panel, you can see we can set our
starting health or max health and whether or not the health component
can take damage. Now as you can see, our
current health is set to 0, but don't worry,
that will get set to 100 or wherever
you're starting. Health value is when
the game starts. And we can easily access
these variables as well as our functions just by dragging in or component dragging out, we can do get current, for example, that gives us access to that
variable we can call our function so increase health that will
run our functions. And we can also, if we wanted to bind events to those
event dispatcher. So we created, so
we could do a sign, we could assign on health
increased for example. And that gives us a event and
the buying event for that. And this will run whenever
our health increases. And it also gives us the
increase amount here as well if we ran our
Bind event at the top. But for now, we'll delete these. Next. We need to setup
our damage event in our third-person character. So to do that, we'll right-click and search for any damage. Will use event and the damage. And we're going to grab our health component
and we want to decrease our health by the damage amount
whenever this event runs. So we'll drag out and we'll
search for decrease health. And we'll connect this
up to the any damage. Then we want damage and plug
it in to decrease amount. And you'll see it gives
us this node that converts the float
into an integer. This will round the value down. So for example, if
I damage was 1.5, this would round it down to one. But we could drag out and do
round and use a round node. And this will actually round
it to the nearest integer. So if it's 1.5, I believe it will
round it up to two. If it was say 1.2, it would
round it down to one. So we'll use around node for
this just because it's a little bit more intuitive. And now, whenever
another blueprint calls the apply damage event
for our character, this event will run and it will decrease our health and
our health component. Now we'll set up
a damaged zone in our level that when our
character enters it, our character will
actually lose health. So it will compile this. But first actually,
we'll just add a print string here because we don't currently
have a health bar. So we just add a print string. And every time we take damage, we want to just get
our current health. So we do get current health, will print out the
current health value so that when we take damage, we know exactly how
much health we've got. I'm going to make the text stay around a little bit longer. So I'm just going to set
duration to five like that. And then we'll compile. Now we'll head over to
the Content Browser. We're going to add
a new blueprint, the blueprint class actor. And I'll scroll down and
we're just going to call this BP underscore damage zone. Like that. We'll drag this into
level and open it up. For this, we're just going
to add a box collision so we know when
something overlaps it. So we'll add a box collision. I'll drag it up a little bit so it'd be flush with the ground. Then we'll head into
the Event Graph and we're going to delete the beginning play and the tech. And we're going to use the
event actor began overlap. And we'll drag out
from other actor, which is going to call
the Apply damage. This is the event that
will actually call the damage inside our
third-person character, we can set the damage amount. So I'm going to say
to him like that. Now we can provide
an event instigator, and this is a player controller. We won't be using this
for damaged zone purely because There's no player
that's causing this damage. It's just an
environmental effect. Then we've got damaged coarser. And for this we will
drag out and do self. And this basically
just allows us to know which actor actually apply the damage
to our character or not any damage you
can see damage cause. We also have that
instigated by pen as well. Next we have the damage class. Now, this is a little
bit more advanced. I'm not going to be
covering it in this lesson, but basically you can create new damage types and
add variables to them. So for example, you could have a fire damage class
on ice damage class, and then you can set
that class in here, then on the receiving end. So on your any event damage, you could drag out
from the damage type and you could actually
get those variables, say the is ice damage or is
fire damage for example. But for now, we're just
going to leave that as the EMT class. But for now, one last thing
we'll do before he says, is select the box components,
search for hidden. And we want to untick
hidden Endgame just so it will be able
to see or damaged zone. So now we're ready
to test this out. We'll compile head to
our third person map. And I'm just going to
make the damage zone a little bit bigger and
move it over here. And now when we hit play, we can run into the damage
box and you can see I, health is decreasing by ten each time we actually enter that box. So that's basically
how we can set up a health system and
we can use that house lists them in other
blueprints as well. Now I wanted to give you
a quick example of how we can set up those bind
events in our character. So say for example, every time your
character took damage, you wanted to play
a grown sound. You could do that nice and
easily with the bind events. So we'll go to the
ThirdPersonCharacter, find the beginning, play them. On the end of here, we
can add some new code. So for our bind events to run, we actually need to bind them. So we're going to do
that on Begin Play. And we're going to grab
our health component will drag out and search for bind on Health decrease. And we want this one hit. Like that will connect
this up to our viewport. And now we need an
event that will actually cool when
I health decreases. So we'll drag out
and we'll do custom. And we want add customer. Then we will call this
the crease, like that. Now, this event will run every time I health decreases
and we can just add a sound so we can do
play sound location. I'm gonna do it at my
characters location, so it will just get
back to location. And we can set this
to a sound I don't have like a grown
or unknown sounds, so we'll just pick compiled
failed for example. We'll just compile. Now when we hit play, we run into are damaged box. We actually get that sound play. And it will play every
time we take damage. Now, playing a sound
is just an example. You could have particle
effects happen. You could run totally different code completely up to you. This is just how you
would run code in your character or
any other blueprint that you're using the
health component. When the health decreases, we can do the exact
same thing with health increase and
with health 0 as well. So now what we're
gonna do is we're going to add a
health component to our cube or interaction example that we created
in our last lesson. So we'll go to that
blueprint, open it up. I'm going to add the
health component here. And just like we did before
in our character blueprint, we're going to add
the apply or sorry, It'd be any damage, the event any damage node. We'll grab our health
component. From there. We wanna do decrease health. We're going to drag out from DynaMesh and just
search for around. And we'll use the round node. Plug that in to decrease amount
and connect this up here. Just like that. Now, our
cube can take damage, just like our character. And what we'll do is we'll
get our current health again like we did in the character. And we'll add a print string. I'm just going to
add an append here. So we'll do append
and we'll put a cube. Health Is like that. And then we'll plug our health
into here just so we know the difference between
our character health and our cube health when it
prints out on the screen. Just like that, r
cubed now has health. We can use those
bind events if we wanted to like we just
did in our character. So we can do bind, health decrease and we could
have something totally different happened in our cube when it's health gets decreased. So this is the power
of components. You can add them to
other blueprints. And assuming that you've set
them up in a modular way, you can just add them and
have them work very quickly. Instead of having to create new health variables on
every blueprint that you want to have health and then new functions to
affect those variables. We can just add one component and we can do all of
that straightaway. So next we're going
to be setting up a projectile that our
character is going to fire out in the direction
that we look at when that project I'll hit something that has this damage node. We're going to apply some
damage to that object. So to do that, we'll head
to the content browser. We'll click Add and create
a new blueprint class. I'm going to select Actor. And we'll scroll
down and we'll call this BP underscore
projectile like that. And we'll open it up. Now the first thing we will
add is a sphere collision, and this will be what actually detects what our
projectile setting. So it will do add, will
search for sphere, and we'll use these
fair collision. I'm actually going to select
it and drag it on top of the D for default seen route. And this will make us fear
the root of our blueprint. Now, next we want to
add a new component. I'm going to add a sphere
and spoke correctly. There we go, sphere. And this is just
what the players will see during gameplay. This is our visual representation
of our projectile. You could use a static
mesh component. If you wanted to, say you
had a bullet or a rocket, you could use that instead. I'm just going to be
using the sphere here, so we'll do that. And I'm going to make mine
a little bit smaller. So I'm just going to scale
it down a bit like that. I'm also going to make my
sphere a little bit smaller. So I'll select the
sphere component and we'll change
the sphere radius, just drag it down a
little bit like that. And now, because our
sphere here is going to be dealing with the
collision sphere, Static Mesh doesn't actually need to have any collision
and we don't want it to. So we'll select the
sphere stack measure, scroll down, and we will
find the collision presets. We're going to set this to no collision and we're
going to turn off Can character step
on to know and we're going to take off
generate overlap events. So now our sphere static mesh
has no collision at all. And all of the collision
is gonna be handled by the sphere collision that
we added at the beginning. Just to make things a
little bit less confusing, I'm going to select
these fears Static Mesh, and I'm just going to rename
this to mesh like that. And then we'll rename our
sphere collision component to collision like that. So we know the difference
between the two components now. Now we also need set up some collision settings
for our projectile. So what we'll do is we'll
go to the collision, will select, it, will go
to Collision Presets. So for our projectiles
collision, we're actually going to
turn this to custom. Then we're going to make
sure Collision Enabled is set to query only. Then for object type, we actually don't have a
projectile object types, so we're going to add one
in our project settings. So let's do that. We'll go
up to Edit Project Settings, and we want to go to the
collision category here. Then in the object channels, we're going to add a
new object channel. I'm going to call this
project title. Like that. We want the default response
to be blocked because most objects in the world are going to block
our projectile. So we want to start to block
and then we'll hit Accept. Now the reason we're doing
this is because we want certain things to
ignore our projectile. So in our character,
for example, if we go to the viewport, we don't want our
capsule here to block projectiles because
it's actually larger than our character is. We want our character mesh to block the projectile's instead. So we're adding a new projectile
object channel because then we can tell our
Capsule Component here to ignore that. And then we want our
mesh to block that. So heading back to our project, our blueprint, we'll select
our collision component. Over here. We want to select the object type and we want
to change this to protect. You can see mine
isn't showing up. We can try compiling and
see if it shows up there. It does. If you're still doesn't, you can try just saving everything and
restarting the engine. Sometimes they do take
a bit to show up. So you can try that if yours
isn't that, but mine is. So we'll select that and
then we'll compile again. And then we want to set
this to block everything. So we'll take the Block
option at the top. And then we want this to
actually ignore ****. So we'll do ignore point. And the reason we're doing
that is in our character, this capsule here is considered
the **** object type. We want our projectile
to completely ignore the capsule and
only hit the mesh. So that's why we take
on ignore for ****. Now the one last
collision saying we want to set to
ignore his camera, we're just doing that
because we don't want our projectile to
affect our camera boom. Because if a projectile passed
through the camera boom, it could make your
cameras zoom in really quickly and then zoom out and
it wouldn't look very good. So just make sure you set
this to ignore for camera. We also want to set Can
character step onto, know that we'll stop our
character kind of trying to stand on this object if it gets too close
to our character. Now we're ready to actually write some code for
our projectile. So we'll head to
the Event Graph. If you don't have this tab,
you can just open it up here. Now inherent, we're
going to right-click and search for event hit. Now, this event will run
whenever our objects are our projectile here
or hit another object. And that gives us some output. So when we do hit something, it gives us a reference
to the component within our blueprint that
actually hit the other objects. So for us this will be the collision component because that's the only one
that has collision. Then we've got other, and
this gives you a reference to the other actor that we hit and we will be using this
to apply damage. Then we've got other component. This gives us a reference to the component in the
other actor that we hit. And we've got hit location. This just gives us the
location of where we hit. We've got hit Normal, which
is the direction that the surface that we hit,
we won't be using this. It's a little bit more advanced. And then we've actually got
down here a hip results. So if we drag out and do
break hit result in C, this is actually the same hint
result we get for tracers. So we can access all of this information
about the object we hit with our projectile. Now, again, this is a
little bit more advanced. We're just going to be
using the other pen here to apply damage to the act of that we will
drag out from event here, we'll search for it, apply, damage will use that node. We want the damaged actor
to be the other pin here. So we're saying we want to apply a dimension to the
actor that we've heard. We can set the damage amounts. So I'm just going to
set ten damage cause. Like I said before, this will be the actor that actually
is doing the damage. So we're in the projectile, this is our self, so we'll
drag out and do self. And then event instigator. We actually will
plug this in because a character is gonna be
sporting our projectile. So what we can do
is get instigator. We won't get
instigator controller. And we can plug that into
event instigator like that. And the way this is working
is when we actually spawn our projectile will have an option to provide
an instigator, and we will do that and
that'll be the character. And now when we apply
damage to another object, we're getting that
instigator value that we set when we
spawn our projectile. We're providing that
to the other blueprint that were damaging just in case they want to access
who actually damaged them. Now, we'll add the print
string here is just so we've got a little bit more
information about who we hit. So we'll add the print string and we'll drag out
from that do append. And we'll just put at
the top projectile hit. And then in the second line, we'll plug in our practice. So we'll get over actor
and plug that in here. I'm just going to add a
space to the end of a hit. So it's two separate
words like that. Now the next thing we need
to do is we don't want our projectile to hit the character that
spawned the projectile. So to do that, we're
going to create a beginning play note like that. Um, we're gonna get our
collision component, drag out from that and do
ignore actor while moving. Now this basically just tells
us collision component, an actor that we want to ignore when the
component is moving. So we'll plug this in. We
want to provide an actor. We're going to use get owner. And we'll plug that in here. And we're going to
take on should ignore. Now, get owner is
another variable that we set when we actually
spawn up projectile. And then we're accessing that and we're telling the collision, Hey, we want you to
ignore hitting the owner. Next we're going to
add a new component. So we'll go to Add, and we're going to
search for projector. And we're going to add the
projectile movement component. This is a component
that's built into the engine and it's
going to do all of the calculations for
us that will allow our bp projectile to actually
move like a projectile. So to start with,
we're going to set the initial speed to 3 thousand. This is the starting
speed of an object. Then we'll set the max speed
to that same value as well. Of course, if you
wanted the object move slower or faster, you can increase or
decrease these values. You'll probably want to
keep these the same. And then down here we've
also got velocity. I'm going to set the
first value here to free thousand as well. So if you were to change
the speeds up here, you'd want to make sure you
do the same for her as well. Right now if we were
to spawn our project, how it actually wouldn't destroy itself once it hits something. So we're going to add a destroy to the end of our code here. So I'm just going
to destroy actor. And that would just
mean that when our projectile hits something, it will become where
it will be destroyed. So now we can compile
and save this, and we've set up our projectile, and now we need to
actually spawn up. So to do that, we're going to go to the ThirdPersonCharacter, then back to the Event Graph, will add in a new input event. So to do that, I'll go over
to Edit Project Settings. Then we'll go to
the inputs category and we'll add a new
action mapping. So we'll just add a new option. And I'm going to call mine fire. And then we'll head back to the ThirdPersonCharacter
would do event fire. And we'll find that under the
action, events like that. Now we need to spawn are actors. So I'll just move this over here so we've
got them more space. We'll drag out from Pressed. We'll do spawn actor. We want the spawn
acts from class. We'll set the class to our projectile's projectile
in CPP protector. Now, the spawn transform
we'll drag out and do make, make transform. Now the location,
I'm just going to be using my actors location. But later on, if you're
making a weapon, you'd probably want to use like its muzzle socket for example. But for now we're
just going to use the characters actor location. So it gets, it gets
mapped to location. And we'll plug that
into the location. And then for rotation, we're going to use the
cameras current rotation. So do get control rotation. So our protects how far
is in the direction that we're currently looking
for collision handling. We want to set this to always
spawn ignore collisions. And then if you remember,
we're using both the owner and instigator inside
our projector for. This node here and also
for this node here. So we need to set those. And we're just going
to use a reference to our own character. So we'll just use self. And we want to plug
this into both of these here and here like that. Now we're actually
ready to test this out. And there's one
thing I forgot to do inside our project settings. So if we go back there, I
created a new action mapping, but I didn't actually set a key. So we need to make
sure we do that. I'm just going to click
the keyboard button here and then left
mouse button click, and that will assign
that to that. Now we can actually
test this out, so we'll hit play and
we'll left mouse button. You can see that
our projectile is spawning and it's flowing out and the direction
that we look. And if we shoot our cube it, you can see our cube
health is going down. Now, make sure you are hitting the cube and not the
ground, for example. So it should say projectile hit BP interaction example
like mine does. The same with R1. Over here you can see it's
got different health value from this one and it's going
down as well when we hit it. Now, there are some other damage events built
into the engine. So if we head to the
ThirdPersonCharacter, will just explain those. If we right-click
and we can search for point points damage, you can find the
event point damage. Now, this works similar
to our any damage. If we move it over here, you can see that we've got
some additional inputs. Now the reason for that is if we call the Apply points damage, you can see that this works a lot like the applied
damage node, but it gives us
some extra inputs. So we've got an input for the direction and
also for hip info. So this will then run this event and it will
provide us with hit Info. It will provide us
with a bone name and this is built into the hit Info and things
like the hit direction. So this node is a little
bit more advanced than the applied damage
and the MD damage, just purely because
it provides us with a little bit more
information that we can receive on the actor
that gets here. And then we provide
that information using the apply point damage node and we can input
those values here. Now there are some
other damage nodes, so it will delete these if we
right-click and search for radial damage in find
the event radial damage. Now this will run
whenever our character receives a radial damage type. And if we right-click and
search for Apply radio, you can see that there's
two options here. We'll start with the top one. So we've got apply
radial damage. Now this is a really
cool node because it does all of the work for us, for things like explosions. So what we do is provide
an origin and this is kind of like the
explosions center. We can set a base
damage and we can set how large the damage zone is. So all objects within the, say, 300 centimeters of the origin will actually take
the base damage. And we can provide
actors to ignore like a line trace for example. So if we just do make re, we can plug in actors
that we want to ignore having take
any radial damage. We can also take
on do full damage. That just means
it doesn't matter where the objects that are in our damaged ranges that will take the full base damage value. Then we have the damage
prevention channels. So you may have an explosion
go off and there's a wall between you and
the explosions origin, you'd probably want the
damage to be blocked. So here is where we set which collision channel actually blocks the damage that
our radial damage does. But for example, maybe
you had a window between you and the explosion. You wouldn't want the glass
to block all of the damage. You'd have your say glass, ignore the Visibility
channel and the explosion damage would go through and hit your character. And then we have another
type of radio damage so we can right-click
search for radial damage. Again. We will use apply radial
damage with fall off. Now this works pretty
much the same. It just allows us to have
a inner and outer radius. Now, objects within the inner radius value from the origin, we'll take the full
base damage and then objects within
the outer radius, but outside of the inner radius will take a reduce
damage amount. That damage amount will depend
on the damage fall off. So the higher this value is, the less damage you'll take, the further away you
are from the origin. If you're still within
the outer radius value, then you can set
a minimum damage. So say this was 600 and
our player was say, 590 centimeters from the origin, you would probably have a
minimum damage, say five. And no matter how far away
you are from the origin, if you're within
the outer radius, you'll always take at
least five damage. And then we've just
got the same inputs from our previous
node down here. Now, both of our
radial damage nodes or apply radial damage nodes, we'll call this
radial damage event. So you can use this one
event and that will be called by both of these
nodes I've just shown you. Those are all of the additional damage events you can use in the engine and they're
built into the engine as well So you can
always access them. Now one thing to keep in mind is this event and the damage will run no matter what type of applied
damage node you use. Even if we use, say
apply radial damage, it will call this event to run, and this will run, but this
will also run as well. So if you have both of these
events in your blueprint, both of them will run whenever
you apply a radial damage. And this is the same
for the point damage. So if you use the point
damage apply node, it will call the event
point damage event. If we find that the event
point damage event, this will run, this event, any damage will also run. So both of them will run. This is just something
to keep in mind. If you have, say, both of these, have all of these
events in your project, this will run whenever you
take any type of damage. So just be careful with that. If you have health
being decreased here, and then again on
these two events, you could end up with your
health being decreased twice. So we can just delete these nodes as we're
not using them. And we're pretty much
done for this lesson. So hopefully you now
understand a little bit more about the built-in damage events that come
with the engine. And also how you can create a health system and add
that to other blueprints. And in our next lessons, we're going to continue adding more features to this project.
55. Gameplay Systems (Health Bar): Hey everyone. In this
lesson we're gonna be adding a health bar widget that's going to use
the values that we've set up in our health component. And then we're going to
add our Health Bar to the BP HUD that we created
in the interaction lesson. So to get started, we're
going to create a new widget. So we'll go to Add then
to user interface, and we're going to
select Widget Blueprint. Then select usual widget. And we'll scroll down and I'm
just going to call mine BP underscore health, like that. We'll open it up. I'm just going to drag
mine up to the top pick. For our Health Bar. I'm going to create some texts that
just says health. Then underneath
we're going to have a progress bar that's going to display how much help we have. We're also going to
add some text to that, that will say our current
health and also on Mac self. Now, to start with,
we're not going to use a canvas panel because remember we're going to add
our Health Bar to our HUD. So we'll use that to choose where our Health Bar is
positioned on the screen. So in here we just need to
add our Health Bar widgets. So we'll start with
a vertical box. So I'll go to panel
and then we'll grab the vertical box and just
add that to the hierarchy. We'll grab some texts, so I just search for text. We'll put that in
the vertical box. Then I'm going to
get an overlay. So we'll search for overlay and we'll add that to the
vertical box as well. And the reason I'm
using an overlay is because I want to have a progress bar and
then I want to overlay some text on top
of that progress bar. So we're going to use
the overlay for that. Now we'll grab our progress bar, so I'll just search for progress and add that to our overlay. And then I'm also going
to get some more text and add that to the
overlay as well. So we'll start by selecting
our top text here. And I'm going to
just change this to say health like that. We can change the settings.
So if you want to, I'm going to make
mine a little bit smaller, like maybe 20. That then next I want to set
the size of my progress bar, but we don't have a size box. So to do that, we're going to select our
overlay right-click Wrap with. And then we want to
find the size box here. So that's just added
in a size box for us. Now we can choose what size our progress bar is going to be. So I'm going to turn on override width and
override height. And I'm going to set
the height to save 30. And then we'll set the width to say three-fifths. For now. Now we're going to
select our progress bar and just tell it
to use up all of the available space
so we'll fill horizontally and
also vertically. Now currently we're
previewing for a 1280 by 720 size screen. So we're going to
change this to from Phil screen to just add desired
size onscreen like that. Just so we can get
a better idea of how big or which
it currently is. Next, we're going to
select our textbook here that's over
our progress bar. And I'm going to change
this just to say 50 slash 100s so we can see
what it will look like. I'm going to change the
size to be a lot smaller. So we'll start with, say, 14 to 16. And we'll align this on
the right-hand side. And we also want to align
at center like that. So now we're going to be
editing this text using code. So to do that, we're going
to need it to be a variable. So I'm going to take on is variable and I'm going to change the name to health text. Like that. We're also going to be
changing our progress bar. So I'm going to
just rename this. You can see it's already
ticked on as is variable. So I'm just going to call
this health bar like that. Now I'm also going to
add a little bit of padding to the
right-hand side because I don't want the
text to be right up at the edge of
this progress bar, will open up the padding and set the right to say five pixels. Oh, sorry, we need to
select our texts there, so make sure you've
got text selected. And then we'll set
the right side to about five pixels,
or maybe four. And that just gives us
a little bit of space between the edge of our
progress bar and our text. Now we can compile
and save this. And we're ready to
actually write the code that's going to control
our Health Bar. So we'll head over
to the graph view. Now to update our Health
Bar and our health texts, we're going to need
to get a reference to the health component that
we added to our character. So to do that,
we're going to add some code to our Event Construct who start just by deleting these two notes because we're
not going to be using them. And then we'll get
our owning place or do you get Owning Player? And this gives us the controller
that owns this widget. So from that we can do
gets controlled ****. And this gives us a
reference to our character, but as a point object reference. And then from that we can
do get components by class. And then we can check, does our **** have the
health component? If it does, then we
want to set that. We'll drag out
from return value. Do you promote a variable? And we call this health
component like that. Now, before we set this,
we wanna do some checks. So first we want to check that we are controlling something. So we'll do is valid
here like that. And if it's valid, then we will allow setting the health
component like that. So now we're ready to
create our bind function. So we'll compile and head
back to the designer view. And we'll start by selecting
our health bar here. And we'll go over to the Details panel and
find the present value. Then we want to use
the bind option and do Create Binding. So to start with,
we want to check is our health component valid? So we'll get the
health component and do is valid like that. That would just stop us
from getting any errors. Then we need to get
our current health and also our max offer. So it will drag out and
do get current health and get max health, like clap. And then we need to divide our current health
by r max health. And this will give us
a value from 0 to one. That we can then use
for our progress bar. But first we need to
convert these to be floats. So we'll do to float. That
will give us this note. It will just copy
and paste that here. Plugger whole fin or
imax health in here. Then we'll use our current
health and do divide. Divide, and we divide our
current health by r max out. And this will give us
a value from 0 to one. And that will tell our
progress bar how far to be. And then we can just plug
this in here like that. Then if our health
component it's not valid, we can just copy and
paste this return value and plug it into not valid
and we'll just return 0. Next, we need a
binder for our texts. So we'll go back to
the designer and we'll select the text inside
our progress bar here. Then for the text value will select bind and do
Create Binding. And we'll do the same thing
with our health components. So we'll get that and
we'll check is valid. And connect this up to our
beginning node like that. Then we want to get
our current health. So get current health and get
the max health like that, which is line, these
are a bit better. Now, we need to actually
return some texts. So we'll drag out from
our return value and use the format text node like that. Then we need an entry
for our current health. So we'll use open bracket, we'll call this current health. And then close bracket. And we'll hit Enter
and you can see that adds a new value for us. So I'll plug our current
health into there. And then in our format
texts value here, we will do a slash and then
we'll do open bracket, max health, and then close
bracket and then enter now. And that creates us a
new Max healthfully. And we'll plug that
in here like that. Then if it's not valid,
we're just copy, paste or return
node and we'll plug that in and just leave
that value empty. So now all of our
code is set up. If we head back to the designer, you can spend as much
time as you like editing this and making
it look how you want. I am going to do one
thing and that's changed the color
of our Health Bar. So I'm going to select
it and I'm going to go down to the Fill,
Color and Opacity. And I'm just going to select this and I'm going
to change it to a nice green color just
to stand for health. And then I'll hit OK,
compile and save this. Now we can add this to our hut, so we'll go back to
the content browser and open up the BP HUD. In the palette, we'll
search for health, and we'll drag in our BP
Health Bar like that. And I'm just going to put mine in the bottom corner there. I'm also going to
change the anchor. So because this is the
closest anchor point, that's where I'm going to use. So we'll set it to the bottom
left-hand side like that. Now, you can resize
the switch it. So if I drag it out, you can see our Health Bar gets
larger and smaller. Or you can take on
size to content. And that will just make sure
that the widget is always the same size as it was inside
this widget editor here. So now we can compile
and test this out. So we'll hit play. And you can see that our value
is showing up at saying a 100 out of 100 if I run
into this box here, you can see that our health decreases each time
I entered the box. If we exhale plan
editor and go to our character blueprint and change our health settings here. So if we select the
health component, say I set the max health to 500 and we set the
starting half to 250. You will see that when
we compile and hit play, I hope by just
automatically updates, it says 250 out 500 and our progress bar is
halfway through as well. So now I'll just X out
and I'm just going to set those values back
to their default. So a 100100. Now if you want to make
any more customizations, you can just go to
your health bar here and make any
changes you'd like. If you want to change the
size of the progress bar, you can select the size box and we can change these values here. If you want to change
the size of the text, you can just select
those and you can change the font sizes here. And also here. We're done for this lesson. Hopefully you now
understand a little bit more about how we can get values from other blueprints and then display
them in a widget.
56. Gameplay Systems (Respawning): Hey everyone, In this
lesson we're gonna be setting up a response system. And that's going
to include a HUD that will display when we die, we'll be able to
click respond button, and that will create
us a new character that will take control of. So to get started, we'll
create our respondents. So we're going to go to
the Content Browser, do add, and we want to add a
user interface and a Widget. Blueprint is gonna
be a use of widget. And we'll scroll
down to the bottom. And I'm going to call
my BP underscore, respond HUD like that. And we'll open that up. I'm just going to drag mine
to the top bar like that. This is going to
replace our normal HUD. So we are going to use a
canvas panel for this. So it will search for Canvas and add that to the
hierarchy like that. Now, I'm just going to
add a simple button to this that we can
collect a response. So we'll grab a button. I'm
just going to drag this in. I'm going to change
the anchor point to the center because I want
my button near the center. I'm also going to change
the alignment to 0.50.5, just so our location is in
the center of our widget hip. And I'm going to set
this to 0 and the x. And I'm just going to
hold shift and drag it down a little bit so
it'll be about here. And now I can add some texts, my buttons, so it
will search for text. I'm just going to drag
out on top of my button. And we'll have this say
re, sport like that. Now I'm going to stop my button
again and just do size to content so it gets bigger
to fit the text here. I'm going to change
the text color to be black just so it's a
little bit easier to see. Again Start button.
Now you could spend as much time
as you want in here making this
look how you want. I'm just glad a bit of text, I'm going to have
again anchor at the center will change its
alignment again to 0.50.5. And we'll set the x to 0. And I'm going to hold Shift
again and just move it down. And I'm just going to
have this texts say you have like that. And we'll have this aligned in the center and size to content. Now we're ready to add some code to our
third-person character. So we'll go to the content
browser and open that up. Now in here connected
up to I begin play, we've got some code that binds a play sound
whenever we take damage, I'm just going to delete this because it's a
little bit annoying. So we'll delete that for now. And we're going to create a
new bind for when I hit 0. So we'll grab our
health component, drag out from that and
do bind on health. And we want Bind Event to on
health 0 here, like that. Then from event, we're going
to drag out and do custom. And we want to add a customer. Then we will call this
character died. Like that. Next we're going to
add a due once notes, so we'll drag out
and do, do once. And this will just mean that
this code only runs once. Then we want to check, is
our HUD currently valid? It should be, but we
want to check anyway. So we'll do is valid. And
we'll connect this up to here. And we're going to
remove our hub now. So we'll drag out and
do remove from parents. And this acts as a way
of destroying a widget. So we'll add this to as valid. And then we want to actually
spawn our response. So we'll drag out from here, do create widget, and we'll
set the class to respond. We want it to be respond HUD, winning player will do get
player controller like that. Then we want to actually set
our responded to a variable. So we'll drag out from
the return value, do promote the variable. I'll call this respond. Then we need to add this
to the player screen. So we'll drag out and do
Add to Viewport like that. Then we want to make sure
that the is not valid PIN is plugged into our
Create Widget node. And now to keep things tidy, we're going to highlight all of this and collapse it
down to a function. So we'll right-click and
do collapsed function, and we'll call this create
respawn, HUD like that. So all of that code is now contained inside
this function here. And we can move this to
be a little bit tinier. We can add some reroute nodes. Two are not valid. Wire here like that. Just to tidy things up. Then we'll compile
and save this. Next, we'll head back
to the Event Graph. Now after we've created
our responded here, we want to disable any movement
inputs for our character. So we'll right-click and
search for disabled. We want disable input. And then we'll do get player controller and connect this up to the player
controller and put her. Now if we wanted
to, we could have a deaf animation play here. Now I don't have any, but what we're gonna do
instead is set up a rag doll. So when we die, our
character would play like a rhabdo effect. So to do that, we'll get
our mesh components. So we want the mesh
component from the Components panel
we're going to drag out and we're gonna do set simulate. We want set simulate physics. And we'll connect this
up to disable input. We want to take this on. Then we'll drag out from
Michigan and we want to do is set all bodies. Spell correctly, Bodies
Simulate Physics here. We want to take that on as well. Then we want to change
its collision profile. So for that we're going to
drag out and do Set collision. And we want Set
Collision profile name. Connect this up here. We want to set this in collision profile
name to rag doll. So capital R and then rag doll
spelled exactly like this. This code is actually
what's going to make our character
rag doll when we die. So we're going to collapse
this to a function as well. So we'll right-click and
do collapse function. And we'll call this start
Greg, though, like that. And again, let's just keeps
things nice and tidy and all of that code is just
contained in that function. Now, like that, we could also add a note in here for our Character
Movement Component. So we could grab that
and do stop movement. And we could do stop
movement immediately. This just means that
our character won't continue to receive
any movement inputs. So once you're done,
should look like this. Now back in our Event Graph, we might want our
character's dead body to disappear after
some amount of time. So to do that, we can
drag out and do lifespan. We want set lifespan. And this is how many seconds
after this node is run, the actor will exist for
before we destroy it. So if I set this to
say ten seconds, after ten seconds, our
character's body will disappear. Now you may want a dead variable that's just a Boolean that's true when the character is dead. We won't be using
it in this example. But if you did, we could create a new variable, call this dead. We could set this here as well, just so we've got
a variable that tells us that we are dead. And you could use that in
other code if you wanted to. Next, we're actually going to
set up a custom controller. And the reason
we're doing this is our character's body
could disappear after ten seconds and then maybe we start idle on the
response screen. Now, if our response code was in the character and it
had been destroyed, if we click the respond button, nothing would happen because our character would
have been destroyed, but the place controller
will always exist. So we want to put our
response code in that. So to do that, we're
going to create a new custom controller, will go to the Content Browser, then add Blueprint class, and then we want the
player controller. And that will create
us a new blueprint. We'll call this BP underscore
example controller. Like now. We'll open that up and I'm just going to
drag mine to the bar here. Then we'll go to
the Event Graph. And then here we're
going to create a new function to actually find the location where we are going to respond our character. So we'll create a new function. I'm going to call this
random respond point. Like that. We're going to add an output. This will be a location. So we want this to be
a vector and we'll call this location like that. Then we're going to do or work disconnect this
return note for now. We'll drag out from this and
do get or actors of class. And with that, we're going
to use the player start. Now, this is an active that's
built into the engine. So we haven't created that actually just comes
with the engine. Then from that we want to
drag out and do length. We'll do is greater than 0. So we're just checking
that there are at least one star in our
level. So we'll do f. And if true will run
at our random check. And if false, we'll just
have to get to a location. So for this, we can
do something like 300 and the Z just to make sure we don't
fall through the ground. But this will only be used if we don't have any player
starts and the level, ideally you always want to have at least
one in your level. So from that, we
can actually make a local variable to store this
just to keep things tidy. So we'll drag out from here, do promote a local variable. We'll just call
this player Scott. I'd like to put a
L at the end of local variables just so it's easy to tell that
they are local. So I'll do players start
capital L like that. Connect that up to here. And I will take the output
and plug that in here. Just keep things tidy. And then we'll get the plaster. We want to randomly
pick one of the entries in this array for our
player, spawn up. For that, we're going
to drag out and we're gonna do get length again. And then we want random integer. We want random integer from
a random integer in range. And then for minimum,
we want this to be 0, and then maximum we want this
to be the length minus one. So subtract one. This will be our max like that. So this will get
us a random number between 0 and whatever the current max number of entries that are in
our player starts. And then from that we can do, we can copy and
paste this variable, do gap and get a copy. And then we'll plug
this into the integer. This tells us which players
start we want to get. Then we just get its location. So we do get back to
location, will return this. So I'll just copy and paste. I return node,
plug location into the location and plug this
over here into true like that. We can make this
a bit straighter, tie this up, and then we'll
compile and save this. Now this function will
get a random player start for our character to be respond that we'll head to
the Event Graph now. And we're going to delete both of these because we're not
going to be using them. Then we're going to create
a new custom events or right-click and do custom. And we want to add a customer. Then I'm going to call this
respawn character like that. And we're going to start with
our random respond point. So we'll get that like that. Then we want to
respond our character. So we'll drag out
from here and do spawn actor from class. Now, for the class
we want this to be whatever our default ****
is in our game mode. So what we'll do is we'll
search for get Game Mode. From that, we can do
get default poem. And this will be whatever
Default Pawn Class we have set in our game mode. So we'll plug that into class. Then for spawn transform, we'll drag out and
do a make transform. I'm just gonna move
this back a little bit so we've got a bit more space. Then we'll take
the location from our random respond
point and plug it into location like that. And we'll set the default
collision handling to try to adjust location, but always spawn because we always want our
character to be spawned. Then we'll click
the down arrow here and we'll set the owner
to be our controller. So we'll just use self and we'll plug that
into owner as well. Now, because we're
in the controller, we just want to possess this new character that
we've responded. So I'll drag out from return
value, do you possess? And we can possess that
character and we can leave the target itself because
we're inside a controller. So now we'll compile
and save that. And we're gonna go back to our respond hard because in here we need to add some
code that's going to run when we press
R respond button, it will select the button
here and we'll go down to the unclicked in
the Details panel. Click that. And then here we
need this to run our response event inside
our example controller. So to do that, we'll
right-click and search for Get Owning Player. And this gives us a
reference to our controller. So all we need to
do then is cost to the example controller. Connect that up to here. And that will allow us to call our response character event. Now when we add all respond
hard to play a scream, we want it to release our mouse so we can actually
collect our response button. So to do that,
we're going to add some code to the
Event Construct, just going to delete
the event tick and the event preconstructed. Then we're gonna do get
player controller again. So we'll do get Owning Player. And from that, we
can use show mouse. We want to set show
mouse cursor to true. Then we want to set the
input mode to game and gy. Then we'll plug that in here. And we want the widget
hair to be self, so we'll search yourself. And this is just telling us
that our mouse cursor is now visible and we're using
this widget as our focus. I'm going to uncheck hide mouse during capture because
all that does is when you hold the left mouse button down and drag while
the widgets visible, it will hide our mouse. So personally, I
don't like that, so I'm going to uncheck that. Now once we've clicked,
I'll respond button. We want our mouse
to be hidden again. So we'll copy this code here, and it will paste that in here. And we'll set our mouse
cursor to not be visible. And then we want to set
the input mode to game. So we'll do set input mode to game only,
will connect up here. And then lastly, we want to hide our respond hard once
we've collected respond. So we'll drag out and
we'll do destroy or sorry, not destroy, remove parents
moved from parents. And that acts like
a destroy node. So when we click our respond, berm will tell our
characters code in the controller to respond
or hide our mouse. And we'll enter game mode only, and then we'll remove our
respond heard from the screen. Now, we're not actually using
our example controller yet, so we need to go
to our game mode. So we'll head to the
content browser and find the third-person game mode. Open that up, you can find
the player controller or the default player
controller class here. And we can change that to be
the BP example controller. Then we'll compile
and save this. Now another thing
we need to add is our characters collision
for when they've died. Now, we don't want
our character to keep blocking things
once they're dead. So we're going to add a
new collision profile. So we'll go up to Edit
Project Settings. And then here we wanna
go down to collision. And then presets. We're going to add a new preset. I'm going to call
this dead ****. We're going to Set Collision
Enabled to query only. We're going to set
object type to **** them for everything else which is going
to take ignore. And then we're going
to take block for both static and dynamic. We're going to use
this collision profile for our capsule. So when the player
dies, heel rag doll, but his capsule will
still be where we died. Now we don't want, if we
respond that us to run over to our body and
hit into the capsule. So what this will do
is make our capsule not interfere with our
player's collision. But it will stop our capsule
falling through the ground because we don't have wild
static and dynamic blocked. Our capsule might just fall
straight through the ground. And now we actually need to
set our capsule to use this. So we'll hit Accept and
then go to third person. And we could add this
into our code here, but I'm actually going to add
mine to the start rag doll. So we'll open that
up and we're gonna get our capsule components. So that's it from our
components panel. Drag out and do Set collision. And we want the
circulation profile name. And we'll just add
this to the anterior. This is gonna be dead ****, spelled exactly like this. Now another thing we're
going to change in our character in the Event Graph is this code here is all being run by our
event begin play. But now we have a
response system. We want to change this to be only run when we
possess the character. So we can right-click and
search for event possess. And we can use Event possessed
and plug this in here. And then we can actually
delete the beginning play. And now whenever this character gets possessed by a controller, it will then run this code. Now another thing we can
add is if you remember, our lockout actor
Tracy is going to be running 30 times a second, but we want to stop that
when we dive because we're no longer going to be
interacting with things. So if you remember, we
created our look at Act a timer and we can
use this to stop it. So over here, we can just
add this onto the end. We'll get our look at timer, drag out from that and do clear and invalidate
time I buy handle. And this will actually
stop our trace like that. And we'll compile this. Now one last thing that we need to changes in our health bus, so we'll head over there and our content browser will
find it at the top here. Open that up. Then we'll head to
the Event Graph. And if you remember,
inheres where we get our pawns health component. The problem with this
right now is now we have a response
system or control or may not have taken control of the **** when this code runs. So all we need to do is
add a one frame delay. So we'll search for delay and we use delay
until next tech. And all this does is add a single frame delay to
when this code will run. And by then, our controller will have taken control of our ****. Now we're ready
to test this out. We'll compile and head back
to the Content Browser. I am going to change
the damage that are damaged zone does so
I'll open that up. I'm going to increase this
to say 40 will compile. And now we can hit play
and test this out. So if I run into
the damage zone, you can see we're
taking 40 damage. And now when I run in
for the last time, you'll see our character dies. Rag dolls on the floor. We can hit respond to
spawn a new character. You can see that our
interaction is still working. If I press E, that's
working correctly. If we run into the zone again, we can kill this
character as well. Now we have a fully
functioning response system. Now you may want to add new spawn points
for your character. So to do that, we can exit out and we'll go to the
drop-down here, then two basic and we can add a new player start just
by dragging this in. We can add in a second one, so it will go to Basic again, then Player Start and
we'll add one over here. Now when we hit play
to play in that step, we may spawn or even one of these new points.
So we'll hit Play. You can see we've actually
spawned at the original one, but if we run into
the damage zone to kill ourselves,
we can respond. And you can see it's respond
me at the original again. But if we do it again, we've responded at different
spawn point. So that's it for this lesson. Hopefully you found
the information useful and you now know how to set up a response system
for your future projects.
57. Gameplay Systems (Crouching): Hey everyone. In this lesson
I'm gonna be showing you how to set up a crouching
system for your characters. Now, you can use any crouching
animations you like. I'm gonna be using
the lesson animations that we used earlier
on in the course. And to download
those, just go to the link in the
course description. You can download that file, then extract them,
and you should end up with a folder that
looks like this. Now we're going to add
these to our project. So all we do is
right-click and do copy. Then go back to the engine. Then we'll right-click
the content folder here. And we want to go
show in Explorer. And that'll bring up
our project files here. And we're just going to
paste these in that. Now you can see it's shown
up in the engine here. Now, yours may or may not
have firewalls inside. So if we open it, you
can see mine is working, but if yours doesn't have
any animations inside, just close the engine and then reopen it and
it should show up. Now the first thing
you need to do is create a new blend space because the lesson animations
doesn't actually include a pre-made blend space
for our crouching, but it does include all of the animations we
need to create one. So it will create
a new blend space. Now, I'm just going
to click Add, then go to animation. And we want to find the
blend space option here. And we need to select
our character skeleton. So that's this one here. You can see it says path game, characters, mannequins,
and then meshes. So we'll select that one. And we're going to
name this blend space, crouch like that. And we'll open that up. I'm just going to drag mine
to the top bar like that. So to get started,
we need to set up our axis so we'll start
with the horizontal. This is going to
be all direction. So search for direction. We're going to set the
minimum value to minus 180 and then positive
value to positive 180. And if you remember from our
blend space is less than, That's because we need to
be able to set an animation for all of the
different directions that our character can be going. Next, we need the vertical axis, so we'll open that and we'll
set this to be the speed. And we'll leave the
minimum axis value at 0. And then our maximum axis
value will be wherever your walk speed is
when you're crouching. So if we are planning to 300, then we're going to
set this to 300. Now this is important because
if I set this to say 600 and we set animations for our crouch walking
at this 600 value. If our character was walking
around when crouched at 300, then the animations that will be played will be in
the center part here. So if we had animations at
the bottom and at the top, we'd get half of the animations from the top and half
from the bottom. And then our animations
wouldn't look very good. So we want our maximum access
value at the top here to be whatever our max crouch
walk speed is going to be. For me, I'm going
to set up to 300, so I'll set this to 300 as well. I'm also going to take
on Snap to Grid for both the vertical
and horizontal axis. Now if you remember from
our animation lessons, we can't actually use our
crouch animation chat because we need to set up our
skeletons to be compatible. So to do that, we're going
to go to characters, then to mannequins, meshes. We're going to open
up SK mannequin. And then here we want to
go to the Windows and then we want to find asset
details and tick that off. For compatible skeletons, we
want to add a new option. And we want this to
be the skeleton that came with the lesson animations. So that's gonna be
this one here you can see it says path less
than animations. So we'll click that one. And then we'll
save our skeleton. And we can close
this asset details and head back to
our blend space. Now, for our animations to
show up in the asset browser, we might need to restart
our blend space, so we'll just save it and close, and then I will reopen it. So that's in my
lesson animations. And we're going to open up
the blend space crouch. And now we should be
able to find all of our animations here
in the asset browser. So it will start just by
searching for crouch. And that should show up all of our crouch animations here. So we'll start with
the idle animation. So I'm going to put these at
the bottom for the 0 speed. So it will grab the
rifle, crouch, idle, and plug that here, here
and here like that. Next we need the walk
forward animation, and that's gonna
be in the center because that's for direction 0. So we're going to
grab the ford option here and drag that to the
top middle, like that. Then we want the backwards, so we'll grab that one
and that's gonna be at both the minus one AT direction and the positive 180 direction. Then we want the left. So we'll grab the left animation
and plug that in here. And then right over here. Now, when we hold control, we can preview our animation and make sure that all of
them are playing correctly, which it looks like they are. Now we can save and close this. We're also close our
skeleton as well. And we're going to head over to the ThirdPersonCharacter
Blueprint. So that's gonna be in
the third person folder, blueprints, and then we'll find the third-person character. Now, our character
blueprint actually has a built-in crouched
system that we can use. So all we need to
do is add an input. So I'm going to
search for input and then we spell it and put the input event
that we go control. I'm going to use
the left control. Then we're going to right-click
and search for crouch. And we want the crouch function. And I'm going to plug
this into pressed and then right-click and
search for on crouch. And we want the crouched connected up to
the release like that. Now currently this one
actually worked because our character doesn't
have can crouch enabled. So it will go to the
Character Movement here and search for can crouch. And we want to
take on can crouch under movement
capabilities like that. So now we can test this out. We'll compile it and hit Play. And now if I press Control, you can see my
camera moves down. And when I move,
I'm walking slower because we're using
our crouch walk speed, but our animations on actually changing because we haven't
hooked up them yet. So we're going to head to
the Animation Blueprint. So it will actually
out plan editor, go to characters
than mannequins, than animations and open up the money Animation Blueprint. And I'm just going to drag
mine up to the top pair. Now, like we did in the animation
section of this course, we have our states lesson. We're going to add a new state
for our Crunch animations. So we'll head to the Anim
graph then to locomotion. Now there's quite
a few different ways that you could set this up. If you look here, we've
got a state for all you do animation and then
I'll walk slash run. Now, our blend space actually has the idle
animations built in. So we can just use one
state for crouching. And it will update
whether or not we're moving or idle for us. But if you're using
a blend space that didn't have those
idle animations. And then you would need
a crouch idle state and a crouch movement state, like we do for our normal idle. And then I'll walk slash run. For us. We're just going to
right-click and use the state. And we're going to call
this crouch like that. We'll open it up and hook up our blend space so
it will drag out and such will blend space. And we want linspace
Claire here. And then in the Details panel, we want to set the blend space to our blend space crouched. You can see it's updated
for direction and speed. We will just compile and
we'll get our speed. So we'll drag out
and do get speed. And we will use the
get ground speed. Now, we need to set up
a direction variable. So we'll do that now go ahead to the Event Graph and we'll
create a new variable. We'll call this direction. We need to set this
to a float like that. Now we're also going to
add another variable for if the character
is crouching. So we'll create a
new one and we'll call this is crouching. And we'll set this as well. We need this to be a
Boolean like that. So now to get our direction, we need our velocity. So we'll right-click
and do get velocity. And that should be
at the bottom here. Then from that
we'll drag out and search for calculate direction. This will take our velocity
and our characters rotation and returned
and direction for us. So we're going to need
the character variable. So we will do get character. And then from that we
wanna do get rotation. We want the get's act of rotation and plug that
into base rotation. And then from our
Calculate direction, we can set our direction. So we'll do set direction. We can hook this up
to our sequences. So I'll add a new pin,
plug this in here, and I'll add to
reroute know just to keep things tidy like that. Now we need to set R is
crouching variables, so we'll drag that in
and create a set node. Then we'll do get movement. And we want the gap
movement component. From that we're
going to do crouch. Spell correctly crouch. And we want the is
crouching node here. And we'll just
plug that into our crouching and then we'll add a new pen to sequence and
connect that up here. Again, I'm just going to
add a reroute now just to keep things looking
a bit too idea. So now we can head back
to our crouch state. And in here we need to plug
in r direction like that. And then we can compile. And now we need to
set up the rules that actually interests
into the crowd stapes. So we'll go to the locomotion. Then we'll drag from
idle to crouch, and we'll also drag from Walk, slash run to crouch as well. And we'll open up the
idle to crouch rule. Then here we just
want to get the is crouching and plug it
into the variable hip. And then we'll do the same
thing in our walk slash rum. And we'll plug that in here. Then we need rules
to go back from our crouch to our idle
or walk slash run. So we'll drag from Crouch to idle and then we'll
open up that rule. And then here we just want to
get is crouching, not true. So we'll drag out and do not beryllium and plug that in here. And then we wanna
do the same thing. We've dragged from Crouch
to walk slash run. Open up that rule. And in here we want to do
the same thing is crouching, not true, so we'll try it
out and do not Boolean. But we also want to
check, are we moving? So we'll drag out from here
and do and plug that in here. And then we want to
get should move, so should move,
plug that in here. So it should look like this. Now will compile and we can
actually test this out. So we'll select the is crouching
variable, take this on. You can see it is going up
and down like it should. So we'll compile and
actually test this in game. So it will head to
our map, hit Play. And now when I press Control, you can see we actually crouch, are crouch, idle
animation is playing. If I walk forward
and side to side, movement animations
are also playing. Now currently our character just faces the direction
that we're moving. And the reason it does
that is if you remember, I walked slash run
blend space is a 1D, so it just has forward
and backwards. It doesn't have side
side animations like our crouch does. So if we wanted to have our side side animations
play while we're in crouch, we would need to change our character's
movements settings. So to do that will
exhale planets to, and if we head back to
our ThirdPersonCharacter, we can select the
character movement. And in here we're
going to search for orientate rotation to movement. You can see that
currently it's turned on, which means whenever our
character moves in a direction, the actor will face
that direction. Turn this off and
compile hit Play. You'll see that if I
move side to side, our character no longer faces the direction
we're moving in. And the reason I animation
is doing this is because we only have forward
and backwards animations. But if we crouch and
we move side to side, you can see that our character actually place the
correct animations. And that's because our crouches a 2D blend space with
animations for each direction. Right now, if I look the camera
in a different direction, it doesn't matter where I look. Our character is always
going to face the same way. So what we could do to change this is to go to the
ThirdPersonCharacter here, then select the top component here to get our cost defaults. And then here we can search for York and we can take on
use controller rotation. You're now when we hit
Compile and hit Play, you can see that I can
move side to side and walk slash run doesn't play very well, but our crouch does. And if I look in a
different direction, you can see our
character actually looks in that direction. So we can change the direction
we're looking at now. Now of course, all of these
settings you can change during runtime when
certain things happen. So for example, maybe you
only wanted to enable or disable orientate rotation
to movement when you crouch, You could do that by just getting the character
movement here, dragging out and
searching orientate, scroll down to the bottom. And you can do set orientate
rotation to movement. We can set this to true when we crouch and untrue
when we crouched. Or we could change that. You're setting that we turned on inside our class defaults here. We could change this. So we could do set, use
control of rotation. You're, and we can turn this
on or off whenever we want. All these settings are
personal preference. It totally depends on how
you want your character to move and how you want the player to be able
to control them. Now, if you wanted to change your characters crouched
movement speed, we can do that in the
character movement here, which get rid of this search. We can just search
for crouch and you'll find the max walk
speed crouched here. You can also change your
crouched half height. So this is how large
the capsule component inside the character will
be while you're crouching. And you can also turn
whether or not the character can walk off a ledge,
wild crouching. Again, these things can
be changed in code. You can just grab the Character Movement Component, drag out, do set the max crouch, and you can change
that max walk speed crouched in code
if you wanted to. Now lastly, maybe
you want to set up crouch to be toggle
instead of hold. We can do that. So we'll
delete this code here and we'll disconnect these
for now and move them back. We'll use pressed and
do a branch node. And here we want to check is the character
currently crouched. So to do that, we'll
get character movement, get the crouched or is crouching will
plug that into here. And if we are currently crouching
than we want to crouch, and if we're not currently
crouching, we want to crouch. So it will reorder
these like that. Now when I hit Play, you'll see if I press crouch. I stay crouched. And
if I unpriced crouch, we go out of Crouch and we don't have to hold
it down anymore. So that's the end
of this lesson. Hopefully you now
understand how to set up a simple crouch system for
your future characters.