Transcripts
1. Introduction: Hello, and welcome
to the Unreal Engine five complete beginner course. My name is Alona Bazade and
I'll be your instructor. If you want to work
with Unreal Engine and become a game developer, this course will be
the perfect choice for you. Here is
what you will learn. Fundamentals. In this section, you'll learn the basics
of Unreal Engine five. We'll start by exploring
the interface, essential navigation tools, and key hot keys to
improve your workflow. Actors. Actors are
the building blocks of any Unreal engine project. In this chapter,
you'll dive into concept of actors,
meshes, and objects. You'll understand how they interact and how to manage
their dependencies. Materials. Materials are the key to creating a visual
engaging project. In this section,
you'll learn how to build and modify materials
in Unreal Engine. Modeling. Unreal Engine offers
powerful modeling tools, and this section will
introduce you to them. You'll learn how to model
directly within the engine, create assets, and
manipulate them to fit your project's
needs. Lightning system. Unreal Engines
lighting system is one of its most
powerful features. You'll learn how to create lighting setups using directional
point and spotlights. We'll also explore
dynamic and stated lighting and learn how
to optimize your scene. Blueprints. The
blueprints allow you to create complex
gambling mechanics without writing a
single line of code. We'll cover visual
scripting in detail, teaching you how to
set up interactions, events, and triggers
between actors and objects. Landscape and master material. This section is all about
environment creation. You'll learn how to build vast landscapes and
terrains for your projects. Then apply the master
material system to automatically populate
your environment with biomes and textures. Gameplay. In this chapter, we'll focus on
gameplay mechanics. You'll learn how to create
interactions between your character and the
environment. Mini game. In this final section, you'll put everything together
to create a minigame. This hands on project
will help you understand the entire workflow
from setting up a project to creating
environments, programming interactions, and finalizing a playable level. This course is structured
to provide you with a step by step approach
to learn Unreal Engine. With practical real
world examples, you'll gain not only
technical skills, but also a deeper understanding of how to approach a game
development process. Let's dive in and start creating with Unreal
Engine five. Mm.
2. Downloading UE5: Welcome to Unreal Engine
five basic stores. Over the next few hours, we will go through
project setup, interface navigation,
environmental setup, and creation of interactable
objects and actors. By the end of this course, you should be able to
comfortably use Unreal Engine five and have basic
understanding of all core functions
of Unreal Engine. This course does not require
any prior knowledge about unreal game death or
C plus plus or CSA. Before we can move
on with the lecture, we need to download
UnreleEngine. If you already have
Unreal Engine installed, feel free to ignore this video
and skip the next lecture. To download Unreal
Engine, first, we need to download
Epicamesauncher. You can do this by going to unrealengine.com and clicking
the Download button. If you don't know how to do it or you have trouble
understanding, please click on WatchOwT Install ink on the
screen to the right. This will send you to a
YouTube video which will explain and walk
through the process. Now that Epic Games
is installed, let's install the engine itself. Click on the Unreal
Engine tap on the left side and go to Library. Here, you can choose which
Unreal engine we need. We will be using Unreal Engine five dot four for this course. For demonstration purposes, I will download five dot three. But here, you need to
click on five Dot four. After you have clicked and
selected your engine version, click the Install button. And now we need to select a
folder for the Unreal engine. Make sure to select
SSD drive if you have one and click on Options. If you scroll down, you may have these four options
selected by default. Unless you're interested in developing for that
specific platform, check them as this will reduce the size required for
your unreal engine. Make sure to keep
starter content, template and feature packs, and engine source enabled. You do not need editor
symbols for debugging. Click Apply and click Install. Real engine five is now going to install
itself on your PC.
3. Create your Project: Now, let's begin by
creating a new project. Click on the launch button and give it a moment
while it initialize. Here, we have a selection
of templates we can use, which are provided by Unreal. We have multiple
selections here for games, film, video, architecture,
automotive, and simulation. For the purpose of this course, we will be using cert
person games template. Make sure to name your project and keep
in mind you cannot use space and the name must be less than 20
letters characters. We now have to select
the project defaults. Click on the blueprint, desktop, Maximum and
keep on starter content. We will not be
using rate racing, but to keep in mind if your project requires
it, you should. All these can be changed from the project after its creation. So in case you need to change something that can
be done later. Click on the Create button. Give it a moment to
create your project. And now your unreal
project is ready. See you in the next lecture.
4. UE5 navigation, hotkeys and fundamentals: Now, let's talk about the windows we have
available to us. On the left side, we have
Place Actors window. It's a window that lets you
drag and drop any actor, object or shape or light, anything really to
your scene easily. You can have your
own created SSP here as well that you can just drag and drop
into the scene. On the right side, we
have world outliner. What does World Outliner do? World Outliner is a
list of every object or actor existing in
your scene in the level. You can click on them here, and you will have them automatically selected
in the level. You can click here and
you can see the name. It is quite useful to
organize your layout. So for example, all blocks
are inside block folder. You can hide them in
combination instead of clicking them
individually and hiding them from the level or
deleting or moving them. You can click or like this, multiple objects at
the same time to move them around at the same
time. It's quite useful. You can move around all windows in your
unreal engine scene. For example, you can take
the outliner, detach it, make a separate window, or you can attach it
in another place, bottom of the screen maybe or
maybe you want it on left. It's up to you, really. You
can remove it. If you want. And if you want it back, you can always go to the
window tap on top and find the window
you just removed. You can have multiple windows
of the same thing as well. So outliner is now back, and I prefer it on the right. We have detail spanel as well. So when you have a
object selected, you get detailed
information here. So let me move this here. On top, as I prefer. And now we have access to the information
about this object. As you can see, as I move this, the transformation
location here changes. I can manually input
any value I want. I can rotate it from
here if I wish so, or scale it up or down. If I want to scale it uniformly, I can click on this lock
button and scale it this way. There's also materials
here and mesh. So here, if you
have an object in the scene that you want to keep all the transformed
location and excess scale, but you want to change the mesh, you can click here and search or just choose the mesh
you want to switch it to. So now I want to change
it to this chair. So I clicked on the chair. Now we have a chair. Let's look at it closely. And yes, now we have
a chair in the scene. If I want to undo it,
I can always control Z. Now I have my cube. If I want to change material, I can just choose a
material from here. Let's try this queen 01. And now our cube
looks different. Let's have a yellowish up
with some metallic for now. It's the same material that
was used for the chair. Now that we are done with looking at the
details and outliner, let's talk about Content drawer. You can click on
Content drawer here, which will let you look at all assets available to
you in your project. The starter content
contains a lot of useful meshes, materials, props, particles to learn
unreal engine, and if you want to just
prototype level for your game. Here, let's go to the props, and we have multiple
meshes we can use from. So let's put a table. And just drag it and
drop it into the scene, give it a moment to
compile shaders. And now you have a
chair in your screen. If you want to have
your content browser visible at all times and not
go down and hide itself, you can click on Doc
in Layout button here. This will let you have
a content browser on your screen at all times. You can put it into
your second screen or as all other windows, you can just attach
it somewhere. So I prefer to have it
on the below my screen. If you have any issues with your layout or let's
say you somehow deleted the windows and you don't remember their
names or how to restore them, what you can do is click
on the Window tab on top. Click on Load Layout and click
on Default Editor layout. This will restore real layout. You can click Control Space and you have your
content browser back, your Details panel,
and outliners Obac. You may notice we don't have
place actors tab anymore. That's because that's
the default layout for Unreal four classic, which we don't really need. Place Actors tab can be
also accessed from here. Everything that's in
the place actors, more or less can
be accessed here, and you can always just
click on a shape you want or an object and you can just have it
pop up into your scene. There are a lot of
other windows in the Windows tab that we will
talk in the future lectures. A few more details about
the unreal interface. If you have an object selected
and you move it around, you will see it's moving at a certain increment,
like it's snapping. This is because we have
this option here enabled. If you increase the snapping, it will only snap in
the increments of 100. If you put it like one, you will see you have
a smooth movement. And if you just disable it, you have even more
incremental movement. I personally like
to have it kept at one or ten for the purpose of having a uniform location
for my objects in the scene. You can do the same with
rotation and scaling. We also have viewport
options here. If you click on the
viewport options here, three lines on the left side, you will have a lot of
options available to you. We will talk about them
in the future lectures, but the one you should probably keep in mind
is screen percentage. If you have screen
percentage enabled, you can click on Custom override and click on the screen
percent you want. If you look at the background here on the lines
on the objects, if I reduce my
screen percentage, the lines will get blur red. This is because this
is now rendering only 25% of the polygons
available in the skin. If you put in 200, it will render them
at higher resolution. I recommend to keep it at
100 to have a good quality. Which is good reference to
how your game will look. Of course, if your game has lower resolution,
settings enabled, you can also essentially
get a good feel about it by putting
into, like, let's say, if your game is going to have a 50% resolution, you
can just put it here, and now this is how
it will look if your game has only
50% resolution or 25 or 200 let's say four K. We will discuss this
in the future lectures There's also selection mode, landscape, foliage,
mesh, modeling, fracture, brushing
and animation tabs, which we will also discuss
in the future lecture. Here, if you press on the play button or
OP in your keyboard, this will go into play mode. What play mode does is
essentially simulates your game. We have the third person
template selected, so we have everything pre
set up for a third person. You can move around
by using WAST jump. And if depending
on the template, some templates may
have a gun which can shoot or a vehicle you can move around with or flying
objects that you can fly with. Now, let's talk about unreal
interface and navigation. To move around your camera, hold right mouse button. If you want to go forward, click W S backwards, left, A, right, T, down Q E for up. You can scroll up to increase or decrease your camera
movement speed. Or you can click and select
your camera speed here. We also have Gizmos to move around the
objects in the scene. By default, if you have
select Objects Gizmo, you will not see anything. If you click W or click on the Select and translate
Objects icon on top, you will get these arrows. These arrows can be used
to move around the object. Or you can click on the circle, move it in three D space. You can also click on
Iki or this icon on top, select and rotate objects, which will let you
use than Gizmo. There's also scale
objects Gizmo. Click R or click this icon on top and you can scale your
objects as you want. To hide your Gizmo, you can always
click Cue button or click Select Objects icon on top here to hide your Gizmo and make sure you don't by accident, move your
objects around.
5. UE5 Actors: Welcome to the lecture.
In this lecture, we are going to talk
more in depth about how to manipulate actors
and objects in the scene. We already touched upon the subject in the previous
video, but in this video, we're going to more in
depth on how to use the hot keys and parameters
to manipulate it. So we have a table here, which can be manipulated with our gizmos as discussed
in the previous video. Movement, rotation, and scale We can also click and hold All Alt
key to duplicate the object. You can shift click
to multiple objects, Alt key move to duplicate
multiple objects as well. If you hold Shift key
and move your objects, your camera will
move along with it. If you press Shift and Alkey at the same time as
you move your object, you will create a duplicate
and your camera will move with a newly created
duplicator of the object. If you pick multiple objects, like I did in now and
try to rotate them, the rotation will happen around
the last selected object. You can easily define which one is by looking
where your gizmo is. If we want to change the mesh
of the object while keeping its location and the parameters
transform parameters, you can do here in
the static mesh. Let's say we want to change
this table into a chair. Thankfully, it's provided
in starter content, so we can just click on it
here and we have a chair. Now, if we try to find the asset location for which
we use this table or chair, and you are not sure where it was located in
your content browser, you can always click on
this icon over here, and it will take you directly
to the asset location. So we can now see content, started content and
props is the folder. And what we can do here, we can click on an object. Let's set the second
table and click on the couch in our content browser and here on the details panel. While this is selected
on the content browser, click on this arochy. This will automatically change the selected mesh into asset we have selected in
the content browser. This works not only for meshes, but also for materials and other types of
assets that are log can be used from the
content browser. Let's say we want to change
this to something else. So let's repeat the process. Let's say, let's take a statue and change
this object to statue. And now we have a statue
to place on the table, which we can do nicely. And let's say we
want a second chair. Easy way to go about this. Click automatically
get selected. Click on this and be. Now we have our chair and the couch and the lamp or whatever this glass
is supposed to be. Now, let's talk about how to
manipulate their materials. So in a similar fashion. Let's say, select this couch and we have materials
folder here. These are standard
materials that come with starter content
of the Unreal engine. And we have options here. As you can see, we have
a material called Chair, which is being used
for this couch. Let's change this material
to something else. Now, let's try it. As you can see, all
I need to do is to just click on the material
and click on the icon. But you can also drag the
material on the object itself. You can select it from the
list if you wish so as well. You may need to wait for it to compile and you can always, as I said before, just click on it and dict it on top
of some material. Let's have it golden. There are additional options here in the details
panel about your object. First of all, if
you notice there's a scale and near the scale,
there's a lock icon. If you don't have it locked and you try
to scale an object, it will scale only in one direction in one
axis to be precise. If you lock it and move
along your transform, it will do it uniformly. Keep in mind, you
can always just type in the resolution you
want, the values you want. And if you are using it with some complicated numbers or scales, do keep in mind. You can do stuff like this. Let's say one plus 00 dot five. The unreal will do
the mass for you. If you want to double the scale, you can just click on multiply
and two. So double it. You can divide as
well as multiply. You can do all mass operations with the values the
unreal gives you. And it's not limited to
only detail s panel. It can be used pretty much
everywhere in the unreal. We have other options here
on the details panel, which are not going
to be covered now. We will cover them later. Now, let's do a task. You have access to
your starter content and all props in it. Go to Props folder and select whatever meshes
you want, static meshes. Drag them, drop
them to the scene and create a small set
the way you wish to. Just test your tools
and get used to them.
6. Managing Actors & Objects: Si. Now, let's talk about how to
keep our scene organized. As you can see, I set up a simple scene here with three chairs, a
table, and a lamp. So let's pick them
all up and move them. So if you want to move our objects as a set
during the level, we have to click on
every single one by shift clicking them one by one or move them independently, which is time consuming
and inefficient. What you would
like to do instead is shift click all of them. And press Control G, group them. Now they are a group of actors, so they are moved as one
and are selected as one. You can shift G to ungroup them and Control
G to group them. You can right click,
go to groups and group or right click
and click group. Same thing. You can also do it from outliner
from the right side here. As you can see, we
have a group actor tab here, which is this. Now, before we move one, there's a tip I would
like to give you. If you want to move a single object out
of all other objects, but you don't want to ungroup them all and group
them back together, which may be time
consuming when you have maybe 40 meshes in
a single group, what you can do is
you can click on these settings on top. Go to A group selection. Click on it, and now group
selection is disabled. This is still a group of actors, but now you can select
them individually. So now let's say
I want to move it closer and this one as well. And now I can click Go to settings and click
Allow Group Selection, and now I can select
them again as a group. This is quite efficient
when you have a lot of measures in the
scene which are grouped together and you don't want to ungroup them and
group them back together. And now we can easily
move it anywhere we want. The scene, let's keep it here. Now, another way we can organize our actors
is by folders. Unreal scene of this level
has default folders already, but the actors we added are
not added to the folder. So let's create a folder. You can create a
folder by clicking on this folder with a plus
icon on the top right. Click it, and if you have
the object selected, it gets automatically
added to the folder. Let's rename this to
let's say per furniture. And let's add this
couch in here as well. What we can do is we can make this bigger easier to see. We have
this folder here. You can just drag
this to the folder. Now our furniture is grouped
together with others. But this furniture is not
part of the grouped actor. It's a separate actor
in the same folder. So do not mix up grouping actors with just having the same actors in the same folder. There
are different things. If you want, you can create
subfolders by doing this. So let's say set one, and let's put our group
actor into set one. Another little task. Let's do some cleanup. Take your previously created
scenes and organize them. Create folders, create groups, if it makes sense to
have them grouped, and just make sure you
have an easy clean scene which can be easily
navigated through outliner. After you are done, move
on to the next lecture.
7. Modeling: Welcome back. As you can see, I have created a
simple set piece using the props in the
starter content folder. And I did some foliage outside, grouped them together, add
some furniture inside, and obviously grouped
them together as well with additional probes, light sources, and glass wall, some pillars, as you can see, and did some cleanup by removing a lot of
clutter from the scene. Added a door and a door frame, and modeled this simple box
using unreal modeling tools. Now let's talk briefly about modeling tools
inside unrele. Unreal has its basic modeling
tools that you can use, but Unreal five dot four has additional modeling
tools available to you, but you need to enable
them from the plugins. If you click Edit and
go to plugin section. These are all plugins
available inside unrele. Some are built in, meaning UnreL provides them by default. They may be on or off. And some are installed
from marketplace or custom plugins that you or
someone else may have created. So there's a lot
of plugins here, so we will not go
through all of them one by one, search modeling. After you search modeling, you will get multiple
modeling tools. I recommend modeling
tools Editor mode, and static mesh Editor
modeling mode. Both of them. They're both beta versions, so they will very likely
be improved in the future by the unreal development tip. After you enable it, I'll ask for a restart. As I have already enabled
it, I don't have to do it, but just click
Restart button and give it a minute for
it to re initialize. After your unreal
has re initialized, go to tab on top and
click Modeling mode. As you can also shift five
to instantly switch to it. In the modeling tools,
we have a lot of things. We will not go into details
for every single one, but anyone familiar with modeling will see a
lot of familiar tools. So if you want to just create a basic shape for
blocking by blocking, I mean just a placeholder meshes that will be used for designing
your level. You can just use modeling
tools inside reel. So the way I created this one, we will recreate it
in a smaller scale. First of all, just click
on a shape you want. In our case, a box. You could also do rectangle, but as you can see, it's just a plane, not useful. We get box. And we need to define the
height, width of the book. By default, it
goes 1-2 thousand, but you can type in
higher values if needed. So in our case,
let's make it 500. Keep it simple. Let's move
it up. Move it around. And I don't want it this small, so let's make it bigger
vertically and horizontally, and I don't want it
to be this sick, so I can reduce the height. So let's do it 20. You can increase the subdivision to increase the quality
of the model, but as we are just using it for prototyping, we
don't have to do it. Now, after we are done with selecting the general
shape we want. And we have a output type, a static mesh, which is
exactly what we need. We could assign a
material here right away, but we will leave it till
later and click Accept. Unless you click Accept, this mesh will not be generated. And after we click Accept, now it's a generated mesh
existing in our level. And if you click on it and
click here to find this mesh, we will see you have a
generated folder and your generated folder as
all the meshes you need. Now, let's go back
to the modeling. So as you can see,
it is just a shape. You may think the best
way to do is just create another shape to make a wall
on right side on left side. But if you pay attention, this is one whole mesh. So if we were to move it
around, it is one whole mesh. It is not just a plane. So the way we do this by using
the simplest way possible, is we click on the mesh
and go to modeling. Well, shape modeling, and
click on poly group Edit. These options on the top, and most of the options, really, will not be
available to you unless you enabled plugin modeling plugin
from the plug in section. After we have select the mesh and click on
polygroup editing. What we need to do
is click on a face. For information, these
dots are called vertices. These lines are called edges, and this face the
side of the meshes, essentially, are called faces. So we click on the face here
and we click on Extrude. What Extrude does is creates a new face and let's
put it like this. The reason why we did this is if we look at the model from below, if we try to extrude it here, it will extrude it whole. We need something smaller. So we extrude it slightly, and now we have a line pace that we can use to
extrude our part. And now we have one
side of the wall. We can repeat this process
here and extrude again. And again, And we have
now a similar shape. In this case, I have not modeled the backside
of the model. It was already a wall there, but we can do that
here if you wish. You can use extruding tools to make any kind
of shape you want. As you can see, you could make complex shapes if you want to. There's a lot of tools here you can use to
modify your models. You can use push pull,
which is similar, but technically
different function that can actually reduce. Technically, as it's named. It pulls or pushes the model. There's bevel, which is not really useful here because I have not
selected any edges, click and select the bevel to There are not a
lot of polygons, so it doesn't look good,
but as you can see, we have modified the
shape of the model. We will not touch this
and we can just cancel it and I will cancel it as well. Again, because I have
not saved the model. The moment I canceled it,
it canceled all of them. Make sure to click except
for your model to get saved. I don't need this model,
so I will just remove it. But I would like to see
what you have created. And don't forget to
clean up your models. As I am not going to use it anymore, I will
just delete it. I could probably rename it to
something more reasonable, but as I will not
be keeping this around for long, I
will not bother. Now, we have a simple set that does not look
really that appealing because of the
color and lighting. It is just gray with
grid, not the best look. And we will change all of
that in the future lecture.
8. Working with Materials: Welcome back. In this lecture, we are going to talk about materials,
how to apply them, how to create them, and how
to modify existing materials. Thankfully, Unreal
has provided us with materials in
the starter content, which we'll be using for
initial demonstration purposes. And after that, I will show you how to create basics materials. As you can see in this level, the grid based texture material while useful for development to eyeball the size and location
of the assets you place, it is not very good looking. So let's change
it. First of all, this floor here does
not look that good. I would like to change
it into something that makes more sense
to be on the ground, and we have some materials here. I could use, I guess, ground concrete. Let's see. Let's use cobblestone, smooth, like, and place it here. Hmm. This looks quite weird. And the reason why
this happened is it's because the material
is stretched out. If you open the material itself, you can see it here,
it looks okay. And if you put a simple
basic shape of let's say, a cube and apply
the same material. This looks quite good as well. The reason why this happens
is because the UV difference. This floor is not really
optimized for this material. So what we can do here, we can open our material and this is a material node
for this particular material. This is quite complicated, but we don't need
a lot from here. What we need to find is to
find texture coordinate node. So All you need to do is find this and you
tile your material. The higher the number, more
squished the textures. You can do it here or here. Click except. Give the moment for it to safe.
And now let's see. It is much better, but
it is still way too big. So let's multiply it by
ten times over again. Maybe 50 and 50. And safe now. Let's give it a
moment. Ideally, you wouldn't want to edit tiling on the
individual materials and use instance material. But I will explain what
instance material are later. Okay. This could be better
if we randomized it but this should be fine
for demonstration purposes. Now we have a smooth
ground floor. And now let's look at this here. I don't really like
this material. So let's use something else. We could use something
fancy like this material here to have this
futuristic look. This material uses
emissive lights. Sorry, emissive material
which produces lights. If you go to the material, you will see there's emissive color noid which
is being applied. We will go through it
later in more detail. But let's for now
increase tiling. Let's say five by
five should be fine. Let accept. Again,
give it a moment. Looks much better. Looks like something from a Sci fi movie. But as we are going to add
lights to this scene later, we wouldn't want this to be conflicting with
the light sources. So let's despite it
being looking so cool, pick a more simpler material. Let's say, for example,
how about this? It looks similar, but
there is no lights. Or maybe. Should we make it from the wood. We could make it from
the wood, as well. Let's make it from the
wood. Give the moment. But, it doesn't look
good. Let's just keep it. Black metal, grid metal. This is a bit too big, so let's tile it a bit more. So let's do 88 and see. Should be good
enough. This floor. Sorry, this all needs to have
material changed, as well. Let's apply to it here as well. This should be fine.
Maybe a bit too dark, but who cares. Good enough. As you can see, we have changed the look of
the whole scene. But these are all materials already existing
in the starter kit. Materials are not
always provided, and there will be times when you want to create them yourself. So let's create a material. Let's go to our content folder. Create a new folder
called material. Open it and right
click or click Plus. You can right click
and create a material by going to here material
and click on the material. There's a lot of things here that are for the future courses. Click on the material.
Let's call it basic M understood score basic. M standing for material. It's good to have
naming conventions for your materials in general. M is usually for materials. So we open it, and
this is what we get. We have output, essentially, and before output,
we have substrate. Substrate is an unreal
specific material function that was recently added.
9. Custom Materials: You may notice that the way your materials look is
slightly different than mine. You have a different
output node, and that's because you don't have substrate
materials enabled. You don't have to use
this specifically, and regardless if
you use it or not, the basic material
functionality, how to create it is the same. Substrate is an expanded
material function for creating layered materials
which are very useful and very much unique
to unreal engine. I have enabled by default, which I would recommend learning if you are interested
in material creation. Now, going back
to the materials. We have some options here. We will ignore everything
on the right side, which are mostly
specific to substrate, and we will focus
on mainly here. Base color, metallic,
specular roughness, normal MSF color and opacity. Base color is, as it
is called base color. The left side, we have
a preview of SR mesh. As you can see
correctly, there is nothing in it, so
it's just white. Let's add a color to this. The way you can do it, you can right click on the
material graph. This is the material
graph, as mentioned here. And you can try to find the
texture node, et cetera, but you can just simply hold three on your keyboard,
numpad, and click. What this does, this creates a constant value that you
can use to select a color. So this is RGB based. So let's select red. We can adjust the color
here the way we want. If you have a X
code or X RGB code, you already know, you can
just copy paste, type it in. And let's say red. As you can see, nothing's
changed here because we have not plugged our node in yet. Let's plug our base
color node here. And now our material is red. But let's say we want to
make it more metallic. We need to add
value to metallic. Usually, the value
is not always, but usually goes 0-1, which means we need a one
float value to put it in. This was sic values, which generated a color. But here we just need one value. So what we need to do
hold one and click, which will create
a single value, which will be the float. Let's put our zero value
node into the metallic. Nothing changed much because the metallic value
currently is at zero, which means it's as much as
unmetallic as it can be. And as I mentioned earlier, one is usually the
maximum value. So let's put a one here and
click N. Give it a moment. Now, suddenly, it
is very different. We can always put a value
in between zero dot five. So let's keep it at one or now. We want it shiny and we
want it to be different. So by the way, you can check
the default values here. So as you can see, specular default value
is zero dot five, which means this is a specular
value of 05 at the moment. Let's add additional fluid
and put it into specular. Now we have specular
value of zero. And do it one you may notice much of a
difference in the screen, but it is quite useful for
non metallic surfaces. As we made it metallic, we will not be able to see it. So let's make metallic
zero and specular one. And now reduce specular to
zero to see the difference. You see? The material
is very matte now. It's no longer
shining because it is a non metallic material
with no specular. So it will not be shining
and reflecting light back. But I prefer my material to be metallic for now,
so let's make it one. And specular does not matter when material is fully
metallic in most cases. So now let's take a
look at roughness. Roughness difft value
is also zero dot five. So we put roughness to zero, which means it is as
smooth as a glass, and it is very reflective
because it is a metallic, fully metallic material with
a completely smooth surface. If you reduce the
metallic value, suddenly, it is just
a smooth object. If you have one for specular, there is some shine to it, but it is not as much as it was when it was fully metallic. So now let's phot one, zero. And again, this is a very
smooth metallic sphere. Specular does not matter when
we have a metallic object, so we will just keep it at zero. And what happens if we
put our roughness up? If you put roughness to one, it is the same
texture as a chalk. The closest thing that is to the value of one
in real life is chalk. For those who don't
know what chalk is, it is a tool used to
write on the blackboard. But this is too much. So let's put into lower value. Let's say 07. We don't want it to
be very reflective, but we want it to be reflective. Maybe a bit more. Sorry, we need to make it lower
because it is in reverse. The less value we have,
more reflective it is. No, a bit more. And,
yep, this is fine. Not too reflective. No
and now we have a normal. So in this case, because we are just making
a simple color material, normal is not as
well useful for us, but normals are used to calculate certain values
in the tangent space. Usually, normal textures are used in conjunction with normal, and value of zero, one is rarely used by default. So let's look at an
application of a normal. Let's say, Oh, yeah, this cobblestone we recently
took take a look at. So we have this normal
node coming here. So we have a normal texture. This normal texture is important for the cobbledon
texture to show up properly. So now let's look at the map. We have this material, or. And in this material, if we go and take a look
at the normal texture, this is a normal texture for the material we
used on the floor. And let's say we remove it or change it
something else, right? So let's change it to normal of a different cobblestone or
even pebbles. And apply. Suddenly, it looks
a bit different. There is something wrong
with the material. Let's do it again. This time, let's
outright change it into texture of a
concrete and apply. Now, these weird lines
on the material, which are from the
normal of cobblestone. It's very important for
normals to match the texture. We need to apply it. I control the twice to restore
what we had initially. Normal textures are
usually created by texture artists or modelers. If you want to learn
how to do it yourself, I recommend to search
for the modeling and texture related information or the courses in our course list. It is very in depth and it can be as
complicated as it can be, so we will not be covering
it in this course. But if you're interested,
please give your feedback. We may rush out a new course
in this particular topic. So let's close this and
go back to the material. Now, it looks the
same as before. Let's go back to
our basic material. We were creating here, we
have something interesting. We have an emissive
color. What does it mean? Emissive color is essentially a material that shines
and produces light. So if we add a value
and put it here, and at zero, it does nothing. If you put it at maybe five, now it is shining brightly. If you put it in, let's say, 5,000, we may go blind. As you can see, it
is emitting a lot of light at the moment. And this material is
not meant to be shiny, so we will just not do this. And keep it at zero is, which is by default. So we remove this. We
also have opacity. If you add a float
note, my apologies, I add another float value and put it into opacity
and put it at zero, the material color will just not show up because
it's at zero. If you put it at let's
say zero dot seven, you have a bit of an opaque. It's kind of hard to see, so
it's left at zero dot two. It is less opaque. In this case, we are
not going to use this, but regardless, it is important to understand how
materials work in general. If you want to make an opaque
material or transluten, let's look at the
material of the glass. So the glass we had it is a starter content
materials, the glass material. Let's take a look at
the glass material. We have reflection
index refraction. My apologies. We have our
substrate shading model. And here we have opacity, and the opacity is 035. We also have additional
refraction, et cetera, which make additional
modifications to edit the surface
of the object. This is way above
intermediate level, so we will skip that. If you take a look at here, we have a very
interesting material which is pretty much almost all black We have a
specular value of ten. As I said, usually, it
goes between zero as well, but sometimes you can go higher. In the case of specular, it is a value of ten. We have a roughness of zero
because this is glass, and we have opacity
of zero dot 35. Because it is a black
material with opacity, it looks like a glass. And if you remove
this refraction here, as you can see, it
changed almost nothing. So don't bother yourself with refraction too
much at the moment. And if we change
this opacity to one, this is no longer a
transparent class. We change the
speculative to one, it is way too dim. There is no
guaranteed way to get the specific result you
want, with a material. So best course of action is to just understand the basic
functions of the material, what they mean, and try to tinker around until
you get what you want. Now, for now, let's close this. We will not save. And
let's go back to this. So here we are back, and we have now this material. And we want this material
to be applied in the low. There is additional options
here for masked additive, et cetera, which will be
covered in the future courses. And we will save this
and go mac the love. Now, let's say we
want these boxes to be the same color as the
newly created material. We go here and select it, and we apply it. Oh, now suddenly we have two boxes with a
material we just created. It is quite that simple to apply the created
material to the level. But let's say we want to
have a metallic material, but we want to have them
each a different color or different amount of
roughness or specularity. We want some maybe
this one to be yellow, this one to be green, this one to be white. It doesn't matter. Does that mean we create a new
material for single one, every single type and variation? No. This is where material
instances come in. So if you have a material, and you want to have multiple
versions of that material, for example, as I said, I want everything to
be here to be exactly the same, other than color. So I want the same amount of reflective surface, metallic, et cetera, and only thing I want to be different
is the color itself. What I can do is I
can right click on the material and create
a material instance. Now, what does this mean? Material instance is a
child of a material, and it takes all its parameters
from the material itself. So now let's apply this
to all these measures. So now we have a
material instance. There are multiple benefits to having a material instance. It is more optimized, and it's easier to
change on runtime. So now let's separate this for a second and take a
look at this, right? Correct. So right now, we don't have anything
in our material. Because we did not add any properties that
we are supposed to be adding and changing
from the material. There are some default
options real has for you, but they are not what we want. So how do we add options here to change during the process? We go to material itself and we find the
parameters we want. And in this case, this one,
we want to change color. So we right click on it. And convert to parameter. So we need to name it. This is color, so
it's simple to name. And now we have a parameter
called color, correct? And the default value for
this material is red. This is all we have to
do. To keep in mind, you can do it for any
other parameters. You could do it for roughness,
metallic, et cetera. We go back and we open the material again.
Let's make it a bigger. Now we have a color. So if we click on this and
change the color here, it instantly changes
the color of all meshes applied with
this exact material. You can change it easily. But you may be asking yourself, wait, but I don't want all of
them to be the same color. Fair enough. Create more
instances of that same material. And this one can be
material instance, two, and apply this one. And this one can be
material instance three. And let's say this is applied to this one and
this one is yellow. Let's do, once again, create material
instance, name it. This one, let's make name four, open it, change it, green. And let's apply this to this. Now we have four materials
of different color. So you may be asking, what is the benefit
of doing this? Because we essentially created multiple
material instances. Couldn't I just create
multiple materials? No. So first of all, material instances
are more optimized, meaning they take
less resources than it would if you had
multiple materials. Secondly, now, we
have four materials, instances, to be correct, which is being applied
to these boxes. And let's say we take this material instance and
we want to change something. But there's additional benefit here if you want to
change all of them. Let's say there was a
difference in opinion later on, and we want to make sure none of these color materials
are metallic. So we want them to be rough, and we change it in the
parent save give it a moment. Go back and now all of
them are nonmetallic. So now we have flexibility to edit materials in the parent, which will instantly change all values not being modified in instance or if you want to change a
specific material only on specific
instance of the mesh, you can just edit
that As I said, we can do it not only with color, we can do
it with anything. So let's say this is a metallic, so we can right click on
it, convert to parameter. Call this parameter
metallic, save. Keep in mind, this is
a parent material. Now if you open any of the instances we
previously created, we have an option here or
metallic, which we can change. So keep in mind. Let's make it more visible. Keep your eyes on this blue box, and let's change the metallic. Now we have only one
of them, non metallic. Obviously, it's better to just have zero
instead of negative. So we can easily modify our materials and our
material instances this way. And this is the recommended
way of doing this. So now let's save this and
take a look at. It's simple. It's nothing too difficult, and it looks quite good for something we created
in a few minutes. Now, before we move on
to the next lecture, let's do another task. With the knowledge you acquired, create materials and
decorate your scene. Good luck and see you
in the next lecture.
10. Lighting system: Welcome back to the course. In this lecture, we are going
to talk about lightning, their differences, and how
to place them in the scene. Before we discuss lightning that can be set up in the scene, let's take a look at
the one that already exists in the scene by
default in this template, which is directional light. And this lightning
here is the sun. If you go to the settings, details panel to be more precise and change
the intensity. I will increase the sunlight or decrease it depending
on the value you put in. At zero, there is no
light, essentially. And at one, it is very low. I personally prefer three, as you can see, but you can
change the value as you want. The light color, as it is
understandable from name, change the light of the color. Sorry, color of the light. You can see, we can give
our scene a different vibe, or now we will keep it as it is. The source angle does not
really matter as much. The default angle here, the source angle is the
same as the sun itself. And if your main source
of light is the sun, you might as well keep
it at this value. This is also not something
you should be worried about. You can increase the
temperature or decrease it, which will affect the color hue. Again, not something you
should really be worried about at this point in time. And we can ignore
the rest of this. We could remove shadows, which will remove all shadows cast it by this source of light. When you have multiple sources
of light in the scene, you may prefer one
specific shadow from that specific
lightning source. So in that case, you can just disable other ones
and keep that one, or you can have multiple lights casting shadow from
multiple sources. And this object will have
multiple shadows from them. But it's better to not
have hundreds of lights, which all of them are
casting shadows in a tight space because that's
just a waste of computation, like optimization for your game. And obviously affect
world is kind of mandatory in most cases. Okay, now let's talk about
the lights that are actually something you can just place into the scene in
a smaller manner. So if we go back to this set we have here,
it is very dark. And let's say we want the sun to be not this
high up in the air. We want something like sunset. We can change the direction of the sun easily by
pressing Control E, sorry, control L and rotating
the sun's direction. So let's something like this. I'm moving around my mouse while holding the
control key down. Yeah, let's do it Lexis. Every time the darker side, and now it makes more sense
to have lightning here. You could always play lights, click on this icon on the
top and go to lights. Or you can click on
the Window tab here, place actors, and go
to the light tub. I will keep it
Lexis just to have an easier time explaining
what each of them does. We already talked about
directional light. You personally wouldn't want to have too many directional
lights in the scene. So usually one directional light from the main light source, the sun is enough, but you may want to have
multiple smaller lights. So let's talk about
point light first. This is point light.
This light has a radius. Let's take it outside,
the camera for a second. The circle around
defines its radius. Let's hide our
sunlight for a second, so we can have
easier time seeing. Source radius and soft source
radius are interlinked. If your source radio is zero, soft source radio does nothing. So for demonstration purposes, let's make it smaller and
increase the source radio. It doesn't have to
be this big to have any effect on soft
source radios. It can be literally one. When I increase this
or decrease it, you will notice
the difference in the lightning on
these far objects. Let's do it like this. What it changed is the fall off at which radius it begins to
have less and less light. Usually, it's not something you have to mold too much over. You can keep it simple. And for now, let's take a look at the last one,
which is source length. So if we put source radius
like this, that's too big. Let's make it this do this. Essentially gives it the height. So rather than a bulb here, now it is a giant it looks like a giant
elevator that emits light. It's not really something you will have to meddle too much, and you can ignore
it most of the time. And let's restore this
light to something proper. It gets bigger. Let's make
it a bit bigger, I guess. And again, it's the
same as before, affect world gets shadowed or not. We can ignore all that. Now, let's take a look at the next type of light,
which is spotlight. You may be wondering
what spotlight does. It's a lightning source that as you can
see from the shape Let's increase the
intensity of it. Is a light that affects
only a certain area. Xis. Let's move the detail panel up so it's easier to see. You can increase the
attention radius which increase the lens. You can rotate it.
As you can see, the X axis doesn't
really do much. But you can rotate
it in Y and Z axis, take a look at M to place
your light the way you want. It is the most commonly
used type of light in games in general in
scenes because if your lamp is in a
certain direction or your light source is supposed to fox on a specific
actor or direction, it is easiest light to
use for these purposes. And we have additional
things here, which is inner core angle, as you can see, increases
or decreases the co angle. What inner cone and
outer con does is inner cone is where the
light is at its brightest. So the intensity of 160 we have here is applied
to the inner cone. So let's do it 40? And outer con is where
the fall off begins. So if we are 40 40, we will have a very sharp flow. If we have inner core at 20, while f off at 40, we will have a soft softer light with a f off after
inner core of 20. If we are at zero, all
of it will be soft. So you could make it essentially into five to focus on a certain
object if there is any. Let's say we have
these cubes here. And if I stop clicking
on the light, so now we have a light
that focus on the objects. So we can increase the radius because it seems
a bit too small, and we can do outer cone
angle even smaller. But not as small, we have an object that's suspiciously lighted
up in your scene. Rest of the options
are same as before. Source of length doesn't
really do much in this case. And we can move on
to our next light, which is rectangular light. So what rectangular light does, it is a source light in
the shape of a rectangle. So let's rotate this to shine
the light on the ground. And let's increase the source
size so it's easier to see. And also, let's change
acenation radio. Of easier time seeing. Unlike previous slides,
this is a particular shape. So if we change the source
height or source width, we will have a specific
shape for our light source. So light now is focused
in this direction. If you change this, second, like this and put your barn
door angle like smaller, it will be a very crisp
rectangular shadow. Then decrease the length or increase it depending on how crisp or square you want
your shadows to be. And you can do it like this to get a very specific
kind of shadow. Now, before we move on
to the next lecture, add some light spots
to your scene. This will be your task for now. If you don't have
any light sources, make sure to just add some. Be creative. You can add
anything. It can be a lamp. It can be a torch. It
can be a fireplace. Do whatever you want
with it, get creative. Don't overthink it and
go way to complex. Just keep it simple. We
will talk about how to do complex lightning with
interactivity in the next lecture. So for now, just make
sure you have some space where you can add your
lights and move them around. Maybe add some color
to your scene. You may want to make a disco, color, whatever up to you. Have fun and see you in
the next lecture. But
11. Blueprint Basics: Welcome back. In this lecture, we are going to talk
about blueprints. So to begin with,
where we left off, these lamps in the wall, we want to add light to them, but we want to add light, let's say, of different colors
or different strengths, or maybe even shapes. We could just manually
add one to each one, like we did with this
lamp in the ceiling. But this is very time consuming. And what if you have not six but 600 lights
in your scene? This is where blueprint and
functionality comes in. To make this object
into a blueprint, let's click on this button here. This converts this actor into reusable blueprint class.
So let's click this. This will ask you
for a subclass. You can just click Select. This is a static Masacor
and this is a actor, going to be a static Mahcor
anyway, so it's fine. And we get this view. This is viewport where we
can look at our object, modify it, et cetera. And perhaps what's even more interesting is this event graph. We also also have a
construction script, which I will talk about
in the next lecture. So this is our event graph. Before we move on, I need to
explain what is a blueprint, what is an actor, and
how it all works. Blueprints are a
visual code system made to help people who want to save time or
who have trouble coding, do their job without
having to code in C plus plus or C sharp in
some other engine. The way this works
is these blueprints are essentially a function
built into your actors. And the question,
what are actors? Every object in your
scene is an actor, and the scene is your level. So this vast emptiness, you see, which is my
level, every single cube, glass, light, Everything, even
the spoil pieces of grass, are all actors. While it may create a
misconception by actor like actor humans or characters in the language of the
code in the engine, actors are everything in your three D scene as with
some small exceptions. For example, this material, the color is not an actor. It's just a visual
addition to your actor. It would be the same for decals or particles that are produced, like all the byproducts of other actors in the scene which are not really
interactable. Or purpose, even
if interactable, they are not something you can just place into
your level as they are. For example, let's say we have a character that
shoots fireballs. The character
itself is an actor. The fireball that it shot is an actor if it's
made as a projectile. But the flame visuals
around the object, which is a projectile
are not actors. They're just components, and that particular
component is particle. The next question is, what is the purpose of
actors in the level? Actors, as I said before, can be anything in your level. There are grass, their walls, their floors, their characters. They are everything that you
need to have in your level. And actors are different. Some actors are
not even visible. Actor does not have to be
visible to be relevant. And what are blueprints? And let's see what's the
difference between this lamp, which is just a static
mesh and this p lamp, which is now a blueprint. The difference is
this static mesh is limited in functionality to
what a static mesh can do. So as you can see, we have our details panel. We have our parameters,
transform, et cetera, some base settings on how engines should interact
with this object. It may be quite complicated to suddenly go
through all of them, so we are not going to touch
upon it at this moment. And quite honestly, you do not need to touch most of the stuff in the details panel unless you know exactly
what you are doing. But actors, which
are blueprints, can contain any kind
of functionality. For example, if I want to
explode this lamp, I can. If I want to make it move
around or fly or do anything, really, I can do all of
this through the blueprint. Obviously, there are
limitations what you can and what cannot do it and
how you want to do it. But the freedom is yours to do whatever you
want with this object. In our case, we want this object to emit
light. This is a lamp. And what we can do to do this is the same as we did
in the previous lecture, we can add a light. So let's add a
directional light. Oh, my apologies. Spotlight. And we want the
spotlight to be looking up, and we want it to be exactly
where the light source is. If you have trouble moving around with your
mouse and zooming, you can scroll down, reduce or increase
the mouse speed, or you can just click on top
here and reduce it here. Let's put it like this. You will see mouth speed is now lower, which is quite useful when you are working with
smaller objects. Also, if you get lost and you are not sure
where your object is, you can always click on
it and press the FK. And if you just press FK, it will zoom in and you
can see your object. This function also obviously
works in the love. So if you have the
selected and move around, press FK, it will snap back to the object you have selected, which is quite
useful when you have multiple objects in the scene
or your level is too big to keep in mind where the object was or you lost the object while you
were dragging it around. Maybe it's under
the floor and you miss selected and you
can no longer see it. And you can just press that key or your object is correctly. So now let's go back
to the blueprint. And we added this light
to the scene, right? Correct. And you may notice this spotlight is under
the static mesh component, which means the spotlight is now attached to
Static mesh itself. If we scale down the object, et cetera, the oldest children
of it will move around. So let's add a cube. This cube is too big, so let's make it a bit smaller. This cube is now attached to
the stack mesh component. So if you scale up the
stack mesh component, while it's five, this cube
will increase in size as well. So this is quite useful
because essentially you are creating a scalable, uniformly scalable
actor that will inherit all its properties from the parent when you
modify it in the level. Let's delete this
cube and compile, save just in case. Now we have the light lamp and light source
itself, the spotlight. We can edit it here and now by let's changing
the radios, et cetera. So let's reduce the radius. I don't want it to be
a too strong lights. Let's put the value
of 500 and compile. After we compile, you can go back to the
level and take a look. Oh, we have a very weak light. I would like it to be
maybe a bit stronger. So increase intensity
to, let's say, t. And come up. It's
still a bit stronger, but I don't like the shape. Maybe it is because
I misplaced it. A bit, yes. It's a bit better. And let's say I want it to be red in the color. Now it's red. But we could have also done this by the usual method just
by attaching it, correct? Here. Why would we do it like this if it's
too bothersome? Because we can add
functionality. So instead of making it red by default, I
will make it white, and I will make the
intensity 20 K, just so it matches
the selling lamp. Pardon. Attentiation
radius is fine with me, and I will compile it and
move on to the event graph. And this is where the most
interesting thing happen. Before we move on, I will
explain what events are. So these are the
three default events that Unreal will put
for you right away. And events are essentially
triggers that start as script. So for example, this
event begin play is going to begin when this actor is in the
level and the level starts. So if this actor is not in the level,
this will do nothing. The actor needs to be in the
level for this to start. So this starts, and let's
say add a print string node, we can add a print string node here and just have
it say hello hello. So print string
is a bug function that lets you debug essentially test the functions
if they trigger or not. In this case, we are just
going to keep it at hello hello and compile and
go back to the level. When we press play, we get hello because the event
began the moment the level we if I were to remove this from the
level and press play, there is no hello
because the level the lamp itself is
not in the level, so this will not trigger. If I somehow spawn or create this blueprint in the middle of the level, this
will begin again. Essentially, this is
what happens when this actor is initialized
and is created. Next is event actor overlap. So to understand overlap, first, we need to
understand collision. If we look at the object, let's pick this store. Let's say this store. This
store has a collision. So the way easily
you can see it is just click on here and
click on player collision, which means collision that
affects the player character. There is also
visibility collision. You may have noticed
there's a slight difference between visible collision
and player collision. This is because this grass on the ground does not have
collision against player. So if we move around, they do not stop us,
cannot interact them. But with this story
and quite honestly, rest of the objects
in the scene does. This is because of the way the collision is set
up for these objects, which we will go through
in the next chapter. But regardless,
back to the point, this object has collision. And by default, this
object does nothing. If you want to add
functionality to the store, first of all, we will need to convert the store
to a blueprint. So what we can do to do this, we click on this button here, and I'm just going to keep
the name right now as it is. It's a good practice to do our name files by
naming convention. Usually blueprints are named BP. And now we have
this new blueprint, and this blueprint is a door. If you close the project and you cannot find
your blueprint, you can always go to
your content browser and find your blueprint. In This case, I
don't like that it is in this folder specifically. So what I will do,
I will move it to the content folder and move
here go to my content. And again, it's not
organized if we have multiple blueprints here, all taking up space, so I will create a folder,
call it blueprint. Um, let's make it
blueprints, just to be. And let's rename
this lamp, as well. And put them into our
blueprint folder. So it's easier for us
to find in the future. Okay, now, this door
has no collision. To be more specific,
it has a collision, but it is just
blocking the player. We cannot really open the door. If we want to open the door, ideally, when we approach it, the door should just open. We could have added some interactivity like
press E to open the door, like in most games, but we could also make
it an automated door. So how do we do this? So first of all, we go to event Craft and we will not be ing tick
or event begin play. So let's remove them.
12. Event Graph: Before we actually just
start coding here, whatever, it's a good practice to just test if your
assumptions are correct. So let's put in a print
string saying hello. So we are hoping that when the actor overlaps
with the door, we get the hello trigger. So let's move to the door
and nothing happens. We may ask why? Because there is a difference between
collision and overlap. Overlap assumes the objects go through each other and essentially overlap
in at certain point. But collision stops
this from happening. So what we do we go back to the blueprint and
take a look at the viewpo. As this door is a solid object, we cannot just go through it to overlap with
our player character. By the way, I just noticed
the door is reversed. So let's just. This
is embarrassing, but let's just apologies. Look, rotate it in
the right direction. I don't know, maybe
there are some doors that have had one on the left. I have never seen one so far.
Other than double doors. Okay, so let's go
back to the door. And here, we need to
add a collision box. We will not be using this box
for collision specifically. This is just a box
to trigger an event. So let's scale it
the size we want. Where it will trigger if the
player character hits it. You can just make it like this. And I don't want this to event to trigger after
we entered the room. I want it to remain open. So let's just do like this, so I don't have to worry about the other
side of the door. So logically speaking,
now the purpose of this is when we the player character overlap with this invisible
box the door will open. But before we can do this, let's remove this and click
on the box that we created. This is the box we have created. And on the right side down
on the details panel, you will see we have events. These are made automatically by unreal to make your
life easier so you can just save time and
just click what you need. In our case, we need
component begin overlap. You may ask, what do
you mean by component and that component is
everything inside the actor. This blueprint itself
is acting as an actor. This static mesh component
here is the core, essentially the root
component of the actor. It cannot be deleted.
It cannot be removed. It can be changed but ideally, the root of the component is what everything is
centered around. And the door part itself
is part of the door, and door frame is actually
the root of the scene. So this internal part of the door is just a touched
static mesh component. And same goes for the box. We could add infinite
amount of well, not really infinite because
of computational reasons, but a lot of
additional components, but in this case,
we don't need them. And we can see here, it says, On component
begin overlap, and in the at the very end, you can see there is box. This is just a name of the
collision we have created. So if we change the name to
let's say, you will get this. I like the box better,
made more sense. We put this now to
here, print string, and to test if this will actually trigger
the overlap event. So we go back to the level, press play, go back to the box. Oh, we have the
hello on top left. We have as you can see, this triggers multiple times every time we enter the overlap. So let's go back
to the blueprint. Now we confirm this
actually works as we want. We could add a lot of limits on what can
specifically trigger this door opening or how
many times it can be opened, closed or do we want to open it and close
automatically afterwards? We can do every single
one of these scenarios, but we're going to
keep it simple. We are just going to open the door when we
approach the door. So now, how would you say the door
is supposed to open here? For the door to open, let's say we want this door
to open let's say in words, you would just need to rotate
this at an angle of 90. Maybe realistically, it
would be something like 80, but I prefer 90 degrees. So what we can do
is we can go here, wreck this SM door node here. By the way, this tor
node now is a variable. Act here in the event graph. And before we moon, let me
explain what variables are. Variables are the most basic
part of the coding process, not only in unreal but also in simplusPlst sharp
and everything else. Variables are essentially
you could say place solders or content of information
that are used to code. For example, like in
the let's say mass, you would be like X plus Y or
X multiplied Y, Y equals Z. This is the same
logic. This is our X. This is our Y. The other
one will be our Z. And when we code, we don't
have to every single time somehow reference or put all the information
associated with the object. We can just put this
as a handle or a tag or however it is you want to accept it easier
for you to understand. This is now our door. The AEM door here, this is a reference to this AMDR and this asm door is now referenced here
in the blueprint. Now, what we can do with this before we need to understand
what we are trying to do. We want to rotate this door
in 90 degrees in the Z axis. -90 degrees to be more specific the Z
axis. How can we do it? So for this, we need
to get a timeline. So timeline and add it here. Now, you may ask,
what is the timeline? Essentially, the overtime
triggers like events, the door. We don't want the door
suddenly snap open. So if we, for example, take this SM door and let's say, take a note from it and
set sorry, rotation. And put in the set
relative rotation to -90 on event trigger. It will instantly open, but this is not
the look we want. You wouldn't want to
have this kind of sudden trigger on your door. So now, how do we fix this? So we want this door
to open over time. So over, let's say, 2 seconds. And the way we do
is with a timeline. So we have this
node which is set relative rotation of the
component it is attached to. In this case is a SM door. This door is the target
for this function. And what this function does is rotates object in
whatever value we put in. We can make it bigger for
the additional nodes, but it's not relevant now. So let's take a look at
what we are modifying here. We are modifying Z axis. We don't really
care about X and Y. So what we can do, we can right click and split this struct pin. So what we did is
essentially split this vector value of rotation
into three float values, which this automatically
converts back to rotation. The reason why we are
doing this this way is because we are only modifying one specific
value out of three, so we don't need to
plug in three values. We take this execution
pin and put it into play. The reason why I put it
into play and not play from start is because we want this to happen
essentially only once. This will play, it will finish, and it will stay finished. If we put it into
play from the start, it will begin every
time this will trigger, this timeline would
begin from the start, but we don't want it, so we're just going
to have it on play. And now we have this ASM
door set relative location, and we need to update this set relative location with a value we will
get from the timeline. So we need to decide what value we are going to output from this into this
relative flotation. We double click on the
timeline and this will open like this and we
click on this plus track. Because we are modifying
only one value. We don't really
need a vector track which contains three vals. You can just use a
simple at flow track. So we have this track, and let's rename it Z axis. And here we need to add a time. So length of the time
is currently 5 seconds. Let's test it with 5 seconds. And the value, we don't
have any values here. It's just a straight
line, nothing happening. So the way we do it, we shift click once
to add a node. So the beginning is going to
be zero. It's no rotation. So we put it into zero, the value also will be zero. And let's add a second node, which will be at five marker. Let's zoom out. It's
going to add 5 seconds. Can put manual time, and the value will be 90 -90 because we are going
a negative number. So this is a very straight up graph from zero to
-90 in 5 seconds. And let's compile it,
go back to Event graph. And now we have this Z
axis from the timeline. It's an output of the value that this function is going to give us every second, not only every second,
like every frame that we will need
to input into here. So now, this Z value that this set relative
rotation function is responsible for is being
updated by this timeline. So we compile this safe just in case and
go back to our love. Now, when we trigger this, the door will slowly
open very, very slowly. And now we're here. If we have done not play, but play from the start for
the trigger, and press, go back to the testing, we would have this weird
situation where, this is opening,
and I move out and I come back and okay,
it's opening again. I come back and okay, as you can see, this
is at best, a prank. At first, a malfunctioning
automated door. So we don't want this. So we do this play. And you may think, what if I want to
close the door? And it's a reasonable question. What if first time I go through
the I when I go inside, I want it to open, and when I go outside, I want it to close. It can be done. The way it
can be done is quite easy. So we could add additional variables
that say if it is true or not that we
are inside or outside, et cetera, in case there are multiple exits
from the building. In our case, we have
only one entrance, so we are going to
just keep it simple. If I exit entered
from this point, and I need to also exit
from this point, correct? And we are going to have
the door remain open. Maybe we just want
it to have some air. What we can do is we
can create a node here called flip
flop. Flip flop. What this node does is the first time this
event is triggered, this will play from the start. And the second time this
event is triggered, it will reverse from the end. Now, let's test it
and take a look. As you can see, this is
triggering every single time. The actor overlaps, and this is not what
we want from our door. So what can we do to fix it? There are multiple ways
to do this as always. What we can do is add a
very simple variable that says if the door is open
at the moment or if the animation stopped
playing or not. So what we can do is we can
create a variable who says I can open close doors.
The bullion value. So the bullion values are values which
just say yes or no. So in this case, can we open
the close and Bulim value? We want this to be yes when the animation
has stopped playing. So how do we implement this? You can press P and click, which will create a branch node. So what branch does is
you put this into branch. And add this value to here. We want the default
value of this to be true because door
is usually closed. At the very start, we want
this to trigger at least once. And if it is true, we want this to play. And if it is playing, we want it to be false, so it cannot trigger
a second time. So what we do before
we move on to here, we create and we
drag this and set open closed door here and
put the value of I too fs. Create a copy of
this, second one, and do the same. We want this to be false in
both cases because this way, this cannot trigger
the second time, but we want it to close after it's finished already opening. So what we do we do this again. On finished, this will
set this to true, and this will be the
end of this line. Now, let's test it this
way. And let's go. A. This does not trigger
again, as you can see. And when I trigger
it again, it closed. So we can trigger
this. Go inside. And when we go outside, we will re trigger it, and
this will close again. Obviously, this is not the
most ideal solution to this. You wouldn't want to have
your door open and, okay, I will go back and come back, and now the door is
closing to your face. There are more reasonable
ways to do this. We can add triggers on
both sides of the door, for example, you can duplicate this and
add another one here. This one will open
when we come in, this will trigger and
we close the door after we are inside
or vice versa, or we can reverse them by using the combination of
blueprints or nodes. But this is good enough for what we are
trying to achieve here. This is a very basic, non optimized way
of opening a door. And this is there are
too many details to this simple function that is just all about
opening the store. We could have done it
in a much simpler way, but there would be
less to explain, so we had to stick with this weird over
complicated solution. Now, this is how we opened the door and
we got into inside. As you can see, this is
thanks to the blueprints. The blueprints enable us to create functions
the way we want. I could do this is just a simple door with
opening and closing animation. We could do it multiple ways. We can have this door recognize this character and
open only to this character. You could have, let's say, MPCs or non playable
characters in the game, and these characters may or
may not trigger the store, depending on the access
level they have. Maybe you want a
specific character to go through this
store, but others know. Maybe you need a specific
item to do this. It all depends on how you want to do it
and your creativity.
13. BP Variables: Well, this is usually
called just exposing the variable to the
editor, essentially. This is not really the
correct name of it. It is instance editable. You may ask what does
Eposon spawn do? So if we have an actor that spawns other
actors into the level. So for example, in this case, let's spawn actor from class and select the spawn
actor as this same lamp. Now we have this lamp
which we can spawn, right? And if we set this. My apologies. We just
need to put a value here. And in this case, I'm just going to skip the
process and expose on spawn. If I compile, but this expose
on span is not available. Let's say I just select it. This will not show up here, even if I compile it. But if I put exposed spawn, now suddenly I have
this function. So this means I can
create an actor that spawns a specific actor
with the parameters I want. How is this useful, you may ask? Let's say you have a game
where you shoot projectiles, fire, ice, electric, I
don't know, laser beam. The color is the only thing that's different between
your projectiles. And this color is defined
per actor upon spawn, similar to what we have here. When they come into existence, they set their light
color, et cetera. But if you want to
set the light color for that projectile upon
spawn, specifically, depending on the parameters, certain parameters you
may have in your game, you can use this expose on spawn to have that option available
to you when you expose it. And obviously, unless
you need this, you leave this off. Okay, now let's go back to what we are trying to do
here in our level. Going back to this
blueprints we have, what if you want to not
set them individually, but every single time
to have a random color? You may just want to
search for it and search random color, and
you will get this. Linear color set random hue. What you need to do is put
your light color here. And this back here and put this s to
here and press play, and they're randomized
every single time. To understand what
this node does, every single time
this node is run, it sets a random value
to this variable, and this variable is set as a light color on a
event begin play. You may wonder why does the color set are not
same for all of them. We only edited one option, one blueprint, and they are
all in the same blueprint. So why is the value
different for each one? This is because this process is called for each
actor individually. So if you play play, and go to the Blueprint. You will see this node. Let's repeat this process. This red line is a function
that just was triggered. And if you take a look
at the top side here, we have different labs, and you can select any of them. Let's select second one and
click on the light color, et cetera, everything
is in place, and you may notice a difference. And you can even
check the other ones. But if you pay attention here, when I hover over
the light color, the values here are
different for each one. And this is because while they are all
the same blueprint, they are individualized their individual
actors in the scene. So when an event is run, event is run for
each one separately. So if you have an object with, let's say, this specific
very simple two node event, and you have 100 of
the same object, you must keep in mind
during event begin play, you run not two nodes of
complexity function, but 200. So make sure you don't
clutter your scene too much. There are ways to optimize this, obviously. You can sequence. You can combine all
actors into group actor. For example, instead of having 100 individual one
light blueprints, you could perhaps have
a light system for your whole city and have them all the lights share
the same blueprint. So in reality, it
becomes one blueprint that's being applied to
all lights in your city. But again, whether it is optimized or not,
easier to use or not, if it is necessary
depends on your game, your creativity, and
more importantly, when it comes to
optimization, your ingenuity. Now we have this function
that is not bad. Every time we take a
look at this room, it's a different color, and perhaps this is classy enough. Perhaps this is all you want. I want it to be a bit more
brighter, so that's 240. Let's see if that
changed anything. Just a bit. Let's change the atentan radius and
angle a bit, maybe 16. Yeah, this is more to my liking. But I want this not
to become stale. So this will remain
exact same way for the rest of the game until I shut it down and
begin it again. This was a game, this would be akin
to entering a room, and the room has all
these different colors, and each time you enter
that room and that room gets loaded into the
game or level opens up, you get different colors. It may be a bit boring. So let's make them change
colors constantly. If we remember Event tick, if you add this everything
here we have in the event ik, instead of events begin play, we will get something
very different. But I believe we can all
agree this is too much. This is hurting my eyes. As such, this is not ideal. Yes, it changes constantly, but I don't want it
to change that much. And this does it only once. We need a middle ground
between overtime, refitting function, and just single ones
at the beginning. There are quite a lot
of ways to do it. You can add timelines, you can call events, et cetera. But easiest way in this particular case is
to add a delay note. What delay does, it waits
a certain amount of time, and that time is referenced
here, duration by duration. And after that time has
elapsed, it executes. Let's say, let's
put it in 1 second. Now, let's take a look at
this and think what it does. During begin play, meaning when this actor
is in the scene and game begins or
when this actor is created or spawn, this triggers. We set a random color to
our light color variable, which is set as a light color for our
spotlight component. And there is a delay. Here. And 1 second elapses and this delay executes,
but there is nothing here. We want to repeat this process. We want to select
a new random color and select set it
as a new light. So what we can do is take this execution
pin and put it here. But suddenly this is very
uncomfortable to look at. What we can do here is
add a rewrote node. Let's add this node here and let's track this
all the way here. Track this node
from here to here. And organize this a bit better. Now, we have a node that re executes here by
delay after 1 second. And let's see what happens. Let's go back to the
level and press play. This is much more
pleasant to the eyes. Now, let's talk about a bit
about blueprint organization. If you are not the only
one in the team or if you just want to
keep it organized, which is a good practice
in general to always have your code organized, there
are things you can do. One of them as
I've shown before, is a rewrote node to make it easy to see where the
execution pins go. So in this case, execution
pin went from delay to linear color set
random hue node. But this doesn't really
explain what this does. And for a person who
first time looks at it, they will need to go through
the code to understand it. And if you have a
very complicated code that has hundreds
of nodes in it, which is not uncommon, you will have the person who takes a look at the code
will have a hard time. To make it easier for them, you can select all of
your code and click C button. This is common. For people who are familiar with coding in plus
plus or C sharp, or any programming language, this is doing exact same thing. This does not add any cost to the project that is
packaged for deployment. Here in the comment section. We just name this. Let's say Light But change function. I'm not sure what is going
on with my keyboard. And now we have this and we
can change the color as well. We want to make it different or just color code or functions. I prefer green, and we don't
want to add this events begin play into this because
event begin play will function regardless
of this code inside. And now, since this all
inside this command section, you can just move
them all together. Which is useful when you will have a lot of
notes in your lave. There is one more thing about this I need to
mention before we move on. This delay note here, you must pay attention. This has icon here. If you read it,
there's a text at the end latent notes can be
only placed in event graphs. You may wonder why this is here. For this notes
familiar with coding, I will have to explain
what a macro is. A macro and functions are they are pretty much the
same as what we have here, but the difference is they
have they are happening instantly and cannot
be time sensitive. By that, I mean, let's
say we have a function, and I don't mean this. These are nodes in a sequence. A function, if we were to
create one here, let's say, we create click on this
plans icon and create a function and call
this function, let's just call it test
as we are testing. Now we have a
function called test. A function can be
called as an event or a node to be more precise
inside your blueprint. And I want to have this all
happen inside the function. I could just copy this and
drag this into the test. But it's much easier to remove this and click all of them and right click and
collapse to function. You will notice this will fail. The reason why this
failed is because of the delay node. We dismiss this. Let's do it again. This time without delay node selected,
collapse the function. Now we have a new function, and let's just copy
the name of this. And rename this new function
into light change function. And then begin play this
looks more organized, and it is also very
good way to do this if you are going to reuse this function specifically
in multiple places. Imagine you have a light and you have multiple possible
triggers to change color. Usually, what you
would need to do, you would need to copy paste. You can remove this
rewrote node, really. You would need to copy
paste this function. To each one of these triggers. So for each event that
has a possibility to change the light color
to random color, we would need to
copy paste them and place them around
the event graph, which will very fast, make it very disorganized. But what's more
important an optimized. An optimized function is a slow function and a slow function makes for a slow game, and no one likes a slow game. Now we have this light
change function, and we can trick this exact
same code by multiple means. Perhaps you have a
game where, let's say, when you touch the light, it changes to a random color. When you perhaps perform a certain action like jumping it changes to
a different color. Or perhaps you shoot it. And let's say you have all three mentioned possibilities in the same game and you want to do all three with
the same actor. Will you create three
separate events for and copy paste that same spaghetti
of code to everywhere? No. What you will use is
this light change function. Now, you may wonder, but, okay, if I have multiple ways of
triggering this function, I would want to have
more control over it. For example, in the after
mentioned scenario, if you can shoot as a light, and you want the
light to change into, let's say, red color
as if it's damaged, You cannot do this
with this function because we set it random
every single time. So there would be
no real difference between by shooting
this, let's say, lamp, which triggers this function, or let's just say
walking around, or maybe there's just another
trigger, doesn't matter. You would need more
control over it. You would want to set this light color
depending on how event is triggered without copying all
these function everywhere. This is where inputs and outputs of the
functions come in. So as you can see here, we have light change function, and there are no inputs there. Target is self in
this case, obviously, but it can be something
else if it's cast, cast cast will be explained
in the next structure. We can click on the light change function
and add an input. Also, we can add an output, but in this case, we're
going to focus on input. Let's add an input. Input, in this case,
is a variable. Now, this light color is a variable called
light linear color. So we want this to
be exactly the same. So we can just type
it linear color. And let's call it just color. And now suddenly we have a light change function with a color node that
we can put into set light color instead of
using light color variable. I will for now, detach this. We may reuse it later. And we can compile. Now, if you go back
to your event graph, you will notice, wait,
we have a color. We now have a way to dictate what color it will
be through a function. So let's make it. Let's say, during events
begin play when the function is called, it turns red. Save, compile, go
back to the level, press play. Okay, it works. But we used to have
random colors. So this is what was
enabling us to do it. So what we can do, we can cut this from
here, compile, get back. And this got here for now.
14. BP Functions: Now, we have this as
a separate function. So this is let's do
collapsed function, call it random color. And we now have
this random color. And for this random
color function, we want to have outputs
instead of inputs. Now we have this
output return node. And when we drag this here
and light color this compile, save just in case. And now we have this
function with an output. To test, we can easily do this. L et's make sure
everything is attached. Let's make sure. Okay.
Let's go back to the level. Yes. It works as it should. But there was no real reason to separate them, you may think. They were one function. It was more optimized to be one function instead
of two functions. But this is where utility comes. What I am trying to do now, when we open the door, all colors will be red. When the door closes, all colors will be green. And when you are
just inside the room or even outside and the door is not being
interacted with, they will change their
colors randomly from time, let's say, in a
five second delay. For this to happen, let's
reorganize our code. We have light change function, and this light change function, all it needs is a color input. We have event begin play, and what we can do
is let's get this in here and add five
second delay here. Perhaps even not five
second delay, let's. Yeah, we will work
on it later on. So what we can do here
is add a new event, and it needs to be
a custom event. And we're going to call
this event Open Door. Door. Let's create
another event, and again, custom event and
call it closed door. Let's make sure it looks fine. Here, we have this function
that takes this random color. Now, do we need to have this function
here? Is the question. Not really. You can
remove this and this. And let's detach them all from each other and
sing about this logically. Game begins, we get
a random color. So we get this random color. We're going to not add
randomization for now. The door opens and
we get green color. Okay? So we need this slight
change function again. But this time, we predefine it to let's
let's say open door, red color as in a warning sign that someone
is entering the room. And for closed door, let's say it is just green. Yes, I agree. And let's say we cannot change the color or
to be more specific, randomize the color of the lights while this
is opening or closing. So let's add a variable. Door is interacted. And add it as a bull in. And let's do branch. To the end of this color. If the door is being
interacted with at the moment, pitch by default value
should be false. We randomize our color
and change it to random colors with delay. F delay. And let's
have this delay be 30 seconds should be fine. Or, yeah, it should be fine. If the door is not
being interacted with, it does nothing. For open door and closed door. When these events are triggered, we want to set this door is
getting interacted into true. So what we do, we get two
sets of set interaction. We set them true, so it does not get
randomized in the middle, and we continue on our process. And if we check our
door blueprint, we had a timeline of 5 seconds. So for door to finish
opening or closing, it takes 5 seconds. So what we can do is add
a delay for 5 seconds. Once second time or you can
just combine them because these two operations
cannot happen at the same time as
we have set up in the Tor blueprint
with this plop, as it cannot get interacted with while one function has
not finished operation. Now, let's go back. And after 5 seconds of delay, we trigger set again. And after we set it to falls, and 5 seconds have passed, we want to get
random colors back. So let's re purpose this and
drag this to random color. And to make it look good, maybe even at a re
rot node to make the curves a bit more easier on the eyes just
to have easier time. Okay. Now, will this work is the main question?
The answer is no. Why? Yes, the lights
are changing colors, but they did not
interact with the door. The reason why this happened, we did not really
trigger the door. We named it open
door closed door, but that's just a naming thing. We just named it that way. We did not really add
anything to trigger this. Now, question is, how do
we trigger this function? This is where we for the
simplicity of the course, just will not use
interfaces and use casts. And I will explain what
they are in a moment. But before that,
let's take this and this when we have
this blueprint here, we have on the A, playing from the start and on the B, reverse from the end. So when B is happening, we are closing the door
and A is happening, we are opening the door. We want to have red color on open and green color on closing. To do this, we need to add execution pin here
that lets us do this, but it's already aquied. The way we do it by sequencing, right click sequence
and click on it. And what we do is we put it in here and we put in first
our play from the start. We want this to happen first, and we do this again, and at a sequence and
zero reverse from end to our blueprint. This is turning into
spaghetti code, but we are just doing this for the purpose of
learning, so it's fine. Ideally, you would
optimize all this code, but it is good for
fast prototyping. Now we have this in place. The question is what we do here. Sequence lets us do certain
executions one by one. It does not really wait for one to finish start
the other one. It is more of a trigger. I will these triggers
zero first, 1 second. Obviously, we want
to open the door, so we put zero to seven
play from the start. And in one, we need to somehow
call these two functions. We need to call this
open door function. The way we can do this,
in our particular level, this store and this lamp will always exist
at the same time. As such, they're already
in the memory of your PC. So we can use casting. Let me first cast the
cast two lamp blueprint. Class. The reason why we
are not going to lamp and class because we want to use it on all lamps
on not a specific one. So we are casting to
the blueprint class, and obviously we need
lampll blueprint. This does. This casting, even if you do nothing
on the other end of it, or even if you
just leave it like this, without execution pin, this will always load the
lamp into the memory. As such, you need to be
careful when you use it, not only casting to class, but also casting to individual instances of the same actor. As it loads it to the memory, every time the store
will exist in the scene, the lamp will be in the
memory and take some space. And even if you don't have
any lamps in the scene, if you have this
specific blueprint door, which has a cast to the lamp
that will be in the memory. So if you right click
and go to Size Map, this will show you how much
it takes space in your game. This is not much, you may think. It's just 3 megabytes. Again, this is very
simple blueprint, but this is on disk size. Essentially how much space
it takes in your hard drive. And if you want to check how much space it
takes in your RAM, your memory, you click
on here, memory size. And as you can see, it takes
11 megabytes of your memory. If you have only
one such object, it's not that much of a deal, but if you have
hundreds of objects which are all casting to
each different objects, and usually they will be bigger than 11 megabytes, suddenly, your RAM is filled
with files and data that it's not even
going to use because these classes are not
always in the level. So you need to make sure if
you are going to cast to something that something
always is in the level, with whatever actor it is
actually doing the casting. For example, casting to the
player character is usually always okay because
your player character is in most games, always loaded into the level as your character
you are playing as. It may be an issue if you have multiple characters and each of your characters functions differently and have
their own blueprints. But in the case of just
having a player character, one same player character
for all levels, you can safely cast
your player character. But as I said, in this case, this lamp, even if you
remove it from the scene, the door can remain but the lamp will still be
loaded to the memory. So you must make sure
to keep that in mind. Okay, now we cast
it to the lamp, and from the lamp, we want a specific function. But you may notice we cannot
really do this directly because this blueprint class is all blueprints of the lamp. It's not an instance or
a specific instance. So we would need to get all
actors of class instead. Which is doing exact same thing, but we will get
an array instead. So we do exact same thing, which again, is very simply. This is going to get a reference to all of them, to
all the actors. This is just not getting
the reference to the class itself directly. So let's do lamp and we
have now all lamps here, but now they are array
in the form of array. So what is an array? Array is a set of multiple
variables in one place. For example, an
array of, let's say, meshes can contain
infinite amount of meshes, and they're array
beginning from zero, like by indexing from zero, one, two, three, four,
et cetera, to infinite. And arrays are very
important to understand if you are going to make a complex game or
even a simple game. Now, in this case, this array here that
was being generated by this function is
getting all assets, to all blueprints of this class. So all references of
this class in the level. In our level, we have six lamps, and this will get us six
actors in the array. What we're going to do, we are going to add for each loop, which means for each
item in the array, we are going to cast to lamp blueprint. Now, you may notice this
has a different color because this is now
not a specific class. This is a specific
object in the array. So for example, in
the first loop, we are going to get lamp
wall on the index zero. Index zero lamp this
will give a note, but the reason why
this is giving us this note is because we are casting to something
that's already casting. But you may notice there
are no other errors. You could put it
directly like this, and to keep in mind,
this is still casting. But the this is just a way to use casting
on an individual actor. If you have only one
lamp in the level, vol blueprint, you can just use direct cast.
There is no problem. But if you have multiple,
you may want to use an array element and see
if it is the same object. For example, if you
have, let's say, an array of multiple actors, but not all actors are the same. For example, we have
an array that contains five doors and five lamps. If you just drag
this here like this, it may not find the
required actor. But if we do it like this
and do this like this, this will only trigger if
the cast was successful. And if the cast by that
successful, I mean, if the cast is lamp and not
the door, this will work. And if it is something else
in the array, this will fail. But keep in mind, you can create your own variables
in the form of array. You can click on the variable. Let's select a
variable of float. And here on the top right, you can click on it and
convert into an array. And you can use after
you compile this array, you can add as many instances
of this array you may want. So we want, let's say, an array of values, five, 12, 14, eight,
two, and one. And if you add this array to the low and get new R, for
example, like this, you can use for
each p function for each loop function to get next value in the order of zero, one, two,
three, four, five, for any other purpose
you need as such, keep in mind, arrays, yes, you can get
an array of items, essentially getting multiple
items by some kind of function as an information and
use for each loop on them, or you can make your
own arrays with specific values or actors references,
and you can use them. Regardless, in this case, we are going to use this note because I want validation that the array I'm getting is actually the lamp
fall blueprint, even if it is unnecessary
in this case, because we all know we
are specifically getting the specific array items and
all of them will be labs. And we're going to compiles
now, what this does? When we open the door, we get all actors of the lamps, and all lamps are one by one in the same essentially
frame instance instant, go through this loop, and these loops calls the function called
not all function, my open door event
in the blueprint. So let's go back to the
lamp pole and press play. Okay, now we are seeing
everything is okay, everything is being randomized. Oh, while the door is
opening, it is red. Now let's wait. After the door has closed, it begins anew. And let's say wait 5
seconds, and it works. And when we go outside, it's not working yet because we did not
add anything to that. So let's see and do it again. We can just copy this
to save some time. And we can call the same
event and at the very end, change it to close door. I believe named it. And if you see context sensitive
now is kind of an issue. When you have enabled, while you are searching
for a function name or an event name specific to a different blueprint,
it may not show up. So we can just disable it and you see class Pvolve blueprint, and we will use this
and we can do this. Also, you can drag it
directly here and close door. Again, as you can see,
it will not show up. So we have this now
working as well, and everything is
as it should be. And we have this. The door is
opening. When we enter it. Now, it's again, random colors. When we exit this, it is green. Now, let's just add one
more small modification to our door so that we can have
a more functioning door. We have this on beginning
component begin overlap. And when we first
time we enter it and exit it, this flip flops. We had two exits or if we want to close the door
after we go into the room, we would need to do it in a different way because the
trigger for it is outside. And even if it was not, the
door closing into our face, would not really
make a lot of sense. When we are trying to do
something weird like, let's do this once, wait for it. Let's say we open the
door, go somewhere else, and next time we come back, the door closing to our face. This doesn't really make sense. So what we want to do instead
is to have a door that opens when we get close and closes automatically
when we go away. How do we do this? We use something similar to
competent begin overlap. But instead, we are going
to click on this SM door, go back here and
Uncompetent end overlap. This does the same
thing as this function. But we need to make sure we
get it for the right event. We need it for the box. This is the exact same functionality. But now, when we finish
overlapping, this will trigger. Which means we no longer really need this branch at the very
beginning or this flip flop. Because it's no longer
a question if we can or cannot do it being flip
flopped from in a sequence. Now, now we have a
different issue. When we want to begin
this functionality, we need to have
now two branches. So we copy this and
this added here, and we do this and do this. But let's test it out and see how it works
after we edit our box. Now, because we want it to contain the door
on both sides, we need to precisely it and let's just make it bigger in
case we have someone saying, Let's not make too big and do it xis and
test how it works. We get close, it starts opening. If you get anywhere
near, it begins again. Now the reason for
this happening is we don't have our previous, it can proper trigger for it. Let's take a look
at our event graph. So when it overlaps, if it can open, close the door, it
triggers and sets this. No, you cannot open close. And this timeline begins and when it triggers
again, this happens. But what we need now
is a bit different. We don't want this to happen
anymore in this manner. If we separate our open here and expand it xis. This is where your second
monitor comes very handy when working with
unreal blueprints. You could dock it
to your screen. Personally, I like having
screen. To myself. Let's begin. And it's kind of hard to see, but
we are opening the door. Okay, now it's opening. And we move, it's closing. But when we come in again,
it doesn't trigger. But it's begin again. And now let's give it a
second and come back. It's instantly
shove to our face. Now, the reason
why this happened, the we always have play from the start and
play reverse from the end, which does not make a lot
of sense in this case, because what if the door is half open when
we approach it? So instead, we are going
to do it play and reverse. What will happen now is when
we play or now it is playing And then we go through verses. But now we have a
different issue. When I go away, it doesn't start closing straightaway.
It finishes it. And next time I go
away, it closes. You may want to
keep it like this. This is more than functional, and it closes and opens up. But let's tweak it around a bit. Instead of having
this branch now, which tells us when we can
open or close the door, let's remove this and have it directly into
sequence like this. This removes any conditional
opening of the function, and let's see what happens now. We press play, we are closed, and it opens, and when
we go away, it closes. And we can go in. It's lipless and we get in and it opens. The only issue is we
made it too slow. So let's go back
to our timeline, and let's make it 3
seconds instead of five. And we need to also change the value of the second one time wise
and make it three. So it rotates in the 3 seconds. But that means also we need to edit the delays on open door, and let's make it
3 seconds as well. This is inside lamp
bull function. So let's see what happens now. We begin the game. We see the lights changing
randomly colors. We get close the
door. It is opening. While opening, it's all red. When it's closing, it is green. And now we're in the loom
with a lot of lights. Now we can also change
the material for this box here and let's
say, add this one. With reduced emissive. Emissive material is as
we mentioned before, it's a bright material. Material brightness is
multiplied here, as you can see. So we can reduce it. We just divide this value. Something I would
recommend doing on the material instance
instead of material itself. But let's say let's
divide it by ten times. Let's see what happens. Yeah, it's less bright. So there's less brightness, but maybe a bit too much. So let's eat four
times less apply. I still want some
brightness to be there. Yeah. And let's apply the
same material here as well. Perhaps not. Again, up to taste. I will leave it here
as it is, save this. And now we have a weird
scene where we have this to some random lights in the middle of nowhere
for our pleasure. The blueprints are a very,
very expensive subject. You can make anything
in the blueprint. There are myriad of
nodes you can twitch, twit around, and add
your own creativity. We did this simple door
function in multiple ways. We took a look at the lights, how we can do it
in multiple ways. And the most important thing
you need to understand is how flexible everything
is in game development. You will not find
simple solutions, and even if you in the future, try to find information on
how to do a specific thing, for example, we have
these cubes here, and when I touch
them, they drop down. These are simple cubes with their physics enabled
and no blueprints. But you could also do
this with blueprints. The difference when
you need to do this is blueprints and when you
can just enable physics, which will be explained
in the next lecture, is what differentiates a good
developer from a bad one. You need to understand
when you need to use what and how and why. There are infinite ways
of doing the same thing. And the complexity
you want to do it as depends on what you need and
what your time frame is. In this case, let's take
a look at our lamps. Yes, this works, and this is
how I showed it to do it. But this is not ideal. We have a lot of nodes. Again, we did not organize them. We have variable that
instead of getting here, we could have inherited
from somewhere else. We did not have to really
use casts for this. We could have used interfaces, which will be explained
in the next lecture. And all of this was
up to create freedom. You've done multiple
things in multiple ways, and it all boils down to what you want to do and
how you want to do it. Don't limit yourself
with your blueprints. And when you search for information on forums
on community forms, maybe on YouTube, Google, and you find the
specific thing you need, do keep in mind, you may have
a better way of doing this. As I have showcased
in this lecture, this store and this lamp, and we did it multiple ways. It's such a simple thing, but it still has infinite
ways of doing it. See you in the next lecture
where we are going to actually make
interactable, small scene, which can be used to
prototype a simple game, and you will have complete freedom on what you want to make and how
you want to make it. But before that, we
will have a task. This task is going to be
a bit more difficult. And in this task, we are going to use all our knowledge we have learned so
far and create and enliven your scene further. I've shown you a few things with how you can
do in blueprints. It was not much as blueprints
are a very expensive topic. But you can apply
what I have shown in the lecture so far to your scenes you have
previously created, or you can just get
creative and experiment with blueprint functionality and create whatever you want. Don't be afraid to make
mistakes or experiment. The only way to really
learn unreal is to actually try to do
it and see if it works. Even best developers will test things multiple times before
they can get it working. See you in the next
lecture. And have fun.
15. Create Landscape: Welcome back. In this chapter, we are
going to go through on how to make a
scene from scratch. We're going to try to create some gameplay elements using all the knowledge we
have acquired so far. And also, I will cover some more functionality
of each aspect of unreal. Until this point, we
have created materials. We have learned how to apply
them and instance them, how to set up the
lightning in our scene, how to create blueprints, and how to create interactivity between blueprints and actors. But we did it all on top of our already
existing template. What if you want to create
something from scratch? So to do this,
let's first of all, decide what we want to keep from this creation we already did. If you have any actor or
object in your scene, you would like to
transfer to the next one. Keep it in mind. And in my case, I want to take some of these cubes with
me to the next level. And I'm going to use
them as blueprint, so I will just click on it, turn them into a blueprint, switch the name, and
just call it Cube PMC. I'm going to save it. The reason why I'm doing is
because I will need it in the next section of the lecture. So to create a new map, first of all, let's
keep it organized, create a folder, call it level. And now let's
create a new level. You could create a level from
here and just click level, but this is always going to be blank as it there is
nothing in the level. If you want to have a
template for a level, you can click on
New level on top, and you will get a choice. Do you want an open
world partition level? Do you want an empty open
world partition level? You want basic or with some assets in it or
empty basics level. The difference between
partitions and basics levels are partition levels are
usually meant for open worlds which are too big. And you would like to
optimize your game play by essentially cutting this
world into partitions, essentially parts to
unload and load into game depends on the proximity
or the state of the game. In our case, we are
not going to do that. We could just use basic,
but I'm going to select Empty level to show you how
it's done from scratch. Let's click Create and save. And now we're in
the empty level. Maybe hard to see, but there is nothing here other
than this grid. And first idea maybe let's
add some light to the scene. But if you just add light, let's say, reactional
light, it will not do much. We need to add the sun, the sky sphere, everything that was by default existing
in the previous level. Do this, you need to go to window and environmental
light mixer. Click on it, and
you will get this. Let's first create the
skylight, atmospheric light. You could edit settings
already if you want, but I'm just to keep
them on default for now, create atmosphere,
create volumetric crowd, and create height fog. And suddenly we
have something very similar to what we had
in the previous level. These are just placeholders for in the outliner where
we have our light sky. So let's put them
all into a folder. And let's call this
folder skylight. At next, we are going
to learn how to create environment
for our scene. There are two ways we can
create our environment. First is just to use some basic measures to create floor walls like
in the previous template. Or you can create a landscape. To create a landscape,
click on the top here, selection mode and
click on Landscape. You will get this grid
on your viewport. And on the left side, we have
our options for the grid. This is how big your
landscape will be. This may seem small, but if you keep in mind
that your meshes should not be too big in the first
place, this is quite big. And landscapes while optimized are still allowed on
your performance. So unless you need them, you should not
make them too big. I want this smaller. So let's reduce
this size by let's divide by and divide
by two again. This is more than enough for me. We could make it smaller, but for now, it should be fine. And we can also pre
select our materials. So let's select ground. Let's see, gravel. I like gravel better. And let's click on Fill world. My apologies. No Fill world. Create. Let's click Create. If you click Fill World, it will fill the whole world with the landscape, which
is not what we want. Great. And now we
have a landscape. As you can see, now it's more apparent that it's quite big. But this is too straight. And I want to add some
mountains and stuff on the side so I can block
vision to make it clear. It's not this. There is no southern
end of the Earth. This is not a flat Earth. So what we can do is
we can use sculptols. So let's click it. And we have a brush.
I want it bigger. So I'm going to
increase brush size, and I'm just going to click
with my left mouse button. Perhaps my brush was too big. Yeah. Let's increase
brush tool string. And let's just sculpt this
landscape just randomly. All I need is to not have a end line that looks bad
and something like this. Maybe a bit more here. Now, if we look
from this vision, let's make it bigger here. I by mistake, clicked on this
spot, but we will fix it. I could control to undo it. But I can also Shift click on it to reverse
to instead create this pit. Or I can click on this flatten tool here on
the top and click on it. Now, the way flatten tool works, you click on a
spot and after you move your mouse while you're
holding that mouse button, it will flatten them to. So we will click on
here and we will move, and as you can see,
everything is being flattened to this point. Fy word click here first
and move my mouse around, it would flatten to
the initial position. So now we have this land. Now let's just add random hills and tops, just kind of fakes
that we are making. Let's add one big one here. Maybe it's a bit too big, so let's let's add some dents
on the ground, fall offs. And now we have a Landscape
you can use for our purposes. Obviously, this is just
something I did in a quick few minutes without putting much
thought or effort into it, but you can create
anything you want. There's a lot of tools here available to you.
You can erode it. You can use hydro to create
a simulation of erosion. For example, let's
pick this rock here, and you may see it's
changing shapes slightly. This is simulating
erosion by rainfall. This one is just erosion from soil moving around
from higher to lower. So this is just a lot
of tools you can use. You can just use noise. You can select what type of
noise you want, et cetera. You could use height maps if you know how to get
them or use them. There are a lot of things you
can do and you can create. And for now, we are
going to keep it here. And what we can do also, if we don't want to have all just this ground
and maybe we want a different color or
mountain and maybe we want the higher up
to be this gravel, but below some grass,
we can do that. For these two, we need to
create a layered material, which we will do shortly.
16. Master Material: Now, let's create our material. The way we will do this,
we are going to create a master material for landscape. So let's go to the
materials holder. We have created previously, create a new material
called M underscore. MM stands for master material, and let's call it landscape. Underscore Matt. Save this. When we save something in the new level for the first time, it
will ask for a name. Make sure to do this
in case you're on real crashes and you'll lose all your progress in the level. And we're going to call it deem you are free to call it whatever you want. And
now this is saved. Save again just gase
or save all materials. We open this material slot. We don't really care about
substrate at this point. We will leave it for later. We need to now
create a material. So the way I decided
to use gravel and grass and we will
have two layers. You can have as many
layers as you want. But keep in mind to not make it too complex because
of performance costs. The way we do it is we need
layer blends or landscape. Landscape layer blends. We add this, and we drag
this to our base color, get a and we add elements equal to the layers we want
in our case, too. And we duplicate this and
copy pass again for normals. If your game does not
have normals, as such, if everything is just
flat, for example, as in Minecraft, for example, you don't really need
normals as much. And because it's a
landscape material, it's good to not have a lot of shininess on the landscape. So let's just force
down value of one. This can also be modified with layer Billions as
all other things, but we are going to
keep it very simple. And now we have two layers. Let's say gravel
for the first one. I should have
probably named them before duplicating just to not have to do this
process twice. And we will call this
one, second one brass. Just copy pass to
here and t for now. We save this, and I have already opened the grass material and gravel material
I'm going to use. And what I really
need to do is copy what's in here for base
color and normals. These two materials are
made by default by unreil. So they have conveniently for
us separated them already. Everything on the bottom
here goes to the normal together with the text coordinate
note So what we can do, we can just copy this all of it. Go to our landscape material, paste all of this here. Let's make sure we have
everything correctly. So out of larp node, we have to base colors. So we do the exact same thing. We add it to the
grass layer blend. Or the larp node. And from
this lp node on the bottom, we have it normal. This may seem a bit
disorganized because this default unreal material
has a lot of nodes in it. But let's just keep
them a bit to side. And let's put them all a bit
below have a clear space. Close this grass material now. Yes, we don't care
about this material. And let's do the
same for gravel, and we do the exact same thing. We copy this. We
paste this here. Let's drag it to the material. And here, we drag this. Let's take a look at this. We have multiply to base color. And let's see what we had here. We had roughness modified. And we have this normal. May have known this because
this gravel material has roughness and grass has a
roughness of default one. We cannot use it as it is, so we will add additional layer blend this time for roughness. We will add this
roughness to gravel. And because grass has
roughness of one, we will just add
the value of one. No need to overcomplicate
this and we save. We give it a second we
go back to our Demo map, we select our landscape. We go down on the details panel and we
have a landscape material. Click on our master material
and put it in here. You will see we
don't really have any color on our
master material. Let's go to landscape
and go to paint. Currently, if we try to
paint, it will not work. To do this, we need
to create layer info. Click on the plus icon. You can do a weight
blended layer, non weight blended layer. We don't really care about
weight too much in this case. So let's do demo map. We can put it in the
material folder as well, just for convenience. And we do it again
for the grass. And again, I will put
it in the material. And now I can select a material, let's say, gravel and paint. You realize this looks weird. If I press here and I grass, this is very shiny. This is a bit too
shiny for my taste. So let's go back to selection mode and click
on directional light, reduce it to three, as I prefer. And now we have less light. Save it for a second. And let's take a look at our specular value
metallic and roughness. Our roughness should be
fine, especially for grass. We need to take a look at
our weight of the map. So we have gravel, but let's first paint the
places we want to have grass. We can take care of it later. I want these areas below to have grass
with lower elevation. Ira elevations can be
just full of gravel. O. Interesting. I will just shift click it
and remove this part. The fact that gravel does not
look correct is concerning. Let's preview the node. You can preview the node of the material by
clicking this icon, and we have it black. Which is concerning. Et's take a look at
the gravel material. Okay. We have a node
that's not attached. Oh, we are missing a note. I may have messed up
and copying the node. Not may, I have
messed up the node. Let's see how it looks now. This still does
not look correct. Let's take a look at it again. For simplicity's sake,
I will just remove this part of the node. Go back to this crowd node, copy all of this again, go back to the
material. Copy pass. We have a Okay, A needs to come from this, and B needs to come from this. I believe I have missed
this note here last time. Apply. Let's take a look. Yes. This is more in line
with what I wanted. And I can now shift click to erase this layer
or just click to add. We're not going to paint
it perfectly here. But as you can, we still
have these values here, brooches, flattens, et cetera. You can also assign foiliage to generate on a
certain layer if you want. In this case, we are not
going to do it for now. We will save. And for now, this should be fine. For now, this should be fine.
17. Foliage: Now, this field here
looks very barren. This is because we
don't have any foliage. We don't have grass, we don't have bushes, we
don't have anything. We could go to foiliage too, and create a foolage or get an active foilage.
We could create it. We could make it ourselves and manually plant them
all over the place. That is not a hard thing to do. We can create just, let's say, static mesh foliage. And let's see. Let's create a new folder. Call it. Foilge. And let's call it Folage Underscoe. Mm. Wolage actor
underscore Bush. Let's open this and go to
mesh and select some Bush. Now, we save this. And if it clicks
and start painting, we will manually paint this
push around the level. Give it a second for it
to finish downloading. Compiling shaders,
be more precise. And now we can just put
them all over the place. We can remove them if we want
and erase them, et cetera. Removing is quite
different from erasing. And you can add parameters here. Let's say we want
it less density. So let's say ten radius or 100. And what is it here now? My apologies. I should
have selected paint. Now we get less foliage. We have additional
parameters here, or it is scale. You may not have mean and
max. This is to randomize. So let's say we
have zero dot five, and just for demonstration,
let's say eight. Some foils are now very big, some fools are very small. We can make them movable, et cetera, but quite honestly, it's not recommended
to have them movable. It's better to have them static. And we have collision.
You don't really want to have collision in foliage because of obvious
optimization issues. You don't want your
car to move around and be stuck on a piece of grass unless a particular kind of foliage is required
to have collision, you should not use collision. Regardless, I don't want
to use this this way. What I will do instead, I will go and remove
part of rays. The way remove
works, you need to select the foiage
and click on Remove, but we don't have
it saved there. So we will just erase it
manually to clean up the scene. We could manually paint
the whole level with this, but this is not really
efficient way of our time. Obviously, if you're trying to create a beautiful landscape, you want to micromanage
every detail. Manual placement
makes a lot of sense. You can place them in singles by just clicking
this single button, or you can place them in fill, just fill the whole
area with it. But I don't want to
waste time on it. So what we're going
to do is instead spawn foilage with the material. For that, first,
we need to create an actor called
Landscape Grass type. I already created one, but I will re demonstrate. Let's go to Foolage. Go to Foolage section, and we have Landscape
grass type. We create this.
Let's call it LG. Let's grass and T
and call it push. The reason why I call it push is because we're only
going to have push, but you can have multiple
grass here elements. In our case, I'm just going to add Bush, so I just
called it Bush. But you could have a set of
different grass together, so you can just spawn
them with one grass. Here, we select our Busch actor. And the reason I'm
using is because it's only one available
in starter content. You can create your own Bushes. You can add something
from Asset Store, from Fab, anywhere you want. And let's save this. We can edit the
density of the grass. We can use, again, the same similar concept
here, maxmin size. And let's make max size two. Calling distance is important. At what distance you
want to see your grass. I will leave it
for now on ten K, but you may want to
reduce it or increase it depending on how important
this grass type is for you. And you may notice there
is no collision in here. The disadvantage, well,
perhaps disadvantage, depending on your game
of using this to spawn your grass or foilage you
cannot add collision to them. So let's go back to
our master material. I don't even know.
That was gravel. So let's go back to
our master material. Right click and call Grass
Landscape grass output. You may notice there
is no place for this. There is no output
node for this. This acts additional
final output node. And we need to add our
grass here. LTG push. Now, let's take a look at
our Just give a moment. You may notice nothing
really happened. This is because we don't have anything in the input section. Now, we need to explain
to the materials where to generate the static
messages for the bush. We have previously
converted into grass type. We cannot just put in this information
here because this is a combination
of layer blends, and there is no real way to generate placement
from our previous nodes. To do this, we need a
sample node, sampler. Or layer Landscape layer sample. And we need to put this in. And here we need to type
in the name of the layer. That layer, in this
case, is grass. You can just copy
pastes or type it in. And safe. Let's see. Suddenly,
we have a lot of grass generated where
our grass material was. I still think it's
a bit too bright. Let's me reduce the
brightness a bit more. Yes. And as you can see, I did not have to paint this, and you may argue
it is too dense. We can reduce the grass density. So let's say I don't want a lot, I just want ten and save. And now I have some grass. I want them generally
to be a bit smaller. So let's mean 02 and max at one. Now we have grass that is
optimized to a degree, and we can just place them automatically by
using a material. Obviously, we can create
multiple layers and each of them can have their own notes. To produce meshes. So let's do another one
this time for gravel. I want small rocks. Let's see if I have any rocks as meshes in the starter content. Rock. We have a rock, I believe. Let's take a look
at it. It's a rock. So let's go through the process
again this time faster. Let's go to our foilage, create a filage
landscape dress type. Call it LGTUnderscore, rock. Open this, add an element, make this element rock, reduce, let's say, size
0-2 to one as before, and I don't want it
to be dense as well, but do it 20. Save this, and let's go to
our landscape material. Here, we can add
a second element. And we can create a
new parameter name, sampler, put it in. We could straight up make two different foolige type
spawn in one layer sample, but we want there to be dirt on gravel layer and grass or in this specifically
bushes in grass layer. So what we need to do
is same as before, we copy the gravel,
parameter name, put it in a second node, go to here, go our second
element, called gravel. Enter, save. Let's go back to our level. There is nothing.
Maybe wondering why. We go back to our material. We have gravel, grass, and we have landscape, but we don't have this second
landscape type selected, LGD rock selected,
and we have rocks. Now, you may notice it is
producing rocks in grass as well because these materials are layered on top
of each other. They are layers. Which means the information the material is getting here is incorrect. We do have rocks, and we have rocks and grass. You may wonder why
this is happening. First of all, let's
reduce the amount of rocks and their
size is too much. Let's make it maybe four and
size can be zero dot one. It seems I have undoed it by mistake and zero dot f.
I don't want big rocks. I want small rocks. Maybe maybe let's add a bit more rocks
here or maybe too much. Yeah, small rocks
here and there. They don't look
good. The fact that they're all the same
scale, I don't like it, so let's add a free
by making it free, it means their scaling in all
directions are randomized. Let's do this like this, save, and probably rocks
will look more different. And I don't like
them being tall, so let's introduce this
scale to zero d two. So we don't have tall rocks. Yeah. We have now
pebbles, et cetera, and let's edit their
clusters as well, which we can do here, maybe. No, this is hardly I need
hardly any difference. Let's restore it as it is. Make a bit more. I don't want cool distance. I want random rotations. Sadly, this is more or less
a limitation of us having not a lot of rock variations. Regardless, let's
leave it as it is. And now the main question is why do we have rocks on grass? This is because the
way layers work. When we were painting, we had these two strengths
here on zero dot three, which means this grass
here is weighted. Despite us using non
weighted layers, this grass here is
actually weighted and we have now the value of
zero dot three on the grass and zero dot seven
on the gravel. The easiest way
to fix this is to remove the gravel
information from here or tool string one and click grass and
just paint it again. But even if we have one grass, it's still not ideal. We want to remove the
gravel information. So we click Shift and remove
the gravel information. Now, if we remove
gravel information, we will not have rocks, and our grass will get more green. Unreal is blending our
two materials together, which is a great
functionality to have. But when you use this to
produce rocks and grass, this may be a demurred. So it's up to you to whether
you are going to use them as a material to
produce the foliage, or you are going to use foliage to paint the tolete and place
them manually in the level. Now, let's clean up the scene
a bit in a fast fashion. Let's I don't want any
grass here on the side. We are going to have a main leak let's remove gravel here. We also remove the
grass, it will be black. So it means black, which means there is
no information here. So if I put gravel
and grass here, you will see in the middle,
they blend together. We can use this to first
of all, let's remove this. Shift click to delete
the layer information. I don't want gravel here to be. What we can do here is we
can add a gravel layer. The sides. The hills and grass layer
on the sides as well, and only grass in the middle. What we'll give us is a
layer with grass foliage only into a blend of
grass and gravel. So rocks and foliage
and only rocks. You can, again, use
multiple layers, use them however you want, create whatever you
wish to create. Now, we will save this. We will not waste any more time on this landscape generation. And do keep in mind
the layer info for this placement for the painting in the landscape is
these two files. Make sure to not delete them or move them from where
they are supposed to. Generally, it's not a
good idea to touch them. You don't really need to do
anything with them, usually. As such, don't touch
them unless it is absolutely necessary and you're aware of
what you are doing. Now we can move on to
creating in our scene. So now we have a landscape. And next, I want to
create something to where we can create our game elements, but
we don't have meshes. And by that, I mean, we don't
have blocks, et cetera, and quite honestly, I don't want to use multiple box for this. So we're going to go
back to modeling tool. And a modeling tool,
let's create ourselves. Let's create
ourselves a platform. We can begin with a cube or a box, if you
wish to call it. Let's put it here and we
can make its height 100. My apologies. Thousand.
Perhaps it's a bit too big. Let's make it 500. And let's see, we can
align it to the ground. We align the targets in
the ground directly. Should I let's just
keep it locally. No need to get too
creative here. Now, we have this enabled. Let's put it a bit
into the ground and we can model this further to
create ourself platform. We can poly group edit this we can enlarge to be
precise, extrude this pace. Select the space, and let's see. What we can do here is push
or pull this face here. Let's do this further. Let's make it a big platform. None real reason
to make it small. And extrude it again. I may have misclicked something. Let's click on this pace again, extrude it slightly and click on this, extrude it again. This will be our part
of our platform. Now let's push this phase. Perhaps I should have
pushed a bit more. I'm making it big just
in case we need it. But quite honestly, you're free to do it anyway
you want, any shape you want. You may have noticed
I made a mistake. I don't have legs for this part because I did
not extrude a proper face. I could add additional edge, et cetera, but instead, what I'm going to do, I'm going to click this and
extrude all the way here. And I'm going to extrude slightly again, create
additional pass. I will click on
the bottom face of the newly created phase
extrude it again, the ground. And now I have this here, which I can easily extrude
again. Look keep in mind. The reason why I'm doing this is just for the sake of
saving some time. As I do not wish to model,
the whole platform. This is very useful
for blocking and creating the samples
for the environment, which later on, you can ask your modelers or
creative to make or if you are going to admire yourself,
yourself can make. Now, we have this, and the ideas this is
attached here to the mountain and have this. We should probably move
this part inwards. So let's do this. What we can do is we can
select all these faces. And just move them to here. Now we have a platform
that's click Accept. And we can further poly group edit, that's
creating pillars. If you want, as you can see, you can just not move this. You can extrude after you select it properly,
unlike what I did. So let's extrude this, make just arena of some kind. That's the idea, at
least in my case. It's just a bit bigger. Extrude again to create additional polygons or
to be more priced faces, I need to push all the way here. This may have been too long, but we will know in a second. You can push it again. Edit this just a bit. Can do the same here. Now, in this case, I'm just
eyeballing the whole process. So it's not ideal. No. I'm just going to at this here. At the pillar extrudes slightly, is a lower face extrude again. Deep into the wall.
It's bit misaligned, so's it is and Let's move all of them together. And it's should be fine. Now, let's be polygroup
edit, extrude the face. Select the pillar,
extrude it again. The height is a bit off. So let's make it a bit taller. You can also select the edges. To move them around, you
want to change the size, and you can shift select them to select multiple
edge at the same time. You want to modify
the size of the face. This is common knowledge when you are experienced
with modeling. And now we can extrude. Again, it's a bit misaligned, but we are not trying
to be perfect here, so we can just do this. And I'm going to
leave it at that. Going to modify this
placement of these vertices a bit by reducing
sitting them here. Yes, I'm not the best
architect, but this is fine. Except now let's select a
material for this platform. I think something like a
marble should be fine. We could Let's see how it looks. Not ideal as we don't
have proper UVs. So let's just create a
new material for this. Go to materials. Let's see how our basic material
looks on this. Yes, basic UVs are fine. You can create a material. Call it underscore plat form. Save Los a platform material. And now we can work on
material for this platform. Save.
18. Scene Setup: Now, we are going to make a substrate
material for our platform. You may ask why? Because we have never touched
upon on the subject, and this is a good opportunity. Substrate material is
a new material type or you could say
material function they introduced in unreal, and it is a way to layer materials without actually using multiple material sources, and it looks and computes the
layers with their alphas, with the lights and
reflections together to give us very high
quality results. So first of all, we need a slab since I removed the previous default
material inputs, and we need a second one if we are making two layered slab
which we are going to do. And we need a vertical
substrate layer. We put it like this, this
here, and this here. This is what we're
going to do for now. Now, this has some similar and options
to the original one. So let's first add our colors. Diffuse albedo is the same as
your color note previously. So let's make it
for now sin blue, add different one and add
it to diffuse albedo here. And let's make it yellow for now. We will
change it later. Let's add a roughness
because I want this top material
to be very shiny. Let's make it 05005. And we have it
like shining blue. But we cannot really see
the yellow. To do this. We need to add this
particular node helper. There are two of them. We need the second one. And
here we drop these to here. And give it a moment.
Now, suddenly, this material looks
very different. Let's save it. You can see this is a
layer of two materials. And if you look at from the
top where light is reflected, you can see the
shine quite easily. And if you look at the bottom, we have a darker color. We could change the color
to make it more clear. Let's say, dark blue and
let's say, deep purple. It's quite easy to see this way. But what's more important
is we can add normals. Normals are for adding textures, so we can just add a texture
node sample, add a normal. And I believe we had some from unreal Sartbrek for
cobblestone, or was it? Oh, yeah, we have normals. For cobblestone we have
smooth ones as well. Let's add smooth ones
and give it a second. And now we have a layered
material with smoothness to it. Let's now make color something we would actually like to see. I want brighter color
with some darker hues. Let's make it on blue. I want essentially two layers. Now we apply this. Let's go back to the level
and see how it looks. Let's give the moment. And let's select our new material
and put it in here. Obviously, we need to
adjust the tiling, but now we have a very
different material. It's adjusted tiling. Significantly. So
extra coordinate. Add TUE, the only
one I have here. Let's make it very high number. Let's tie up ten times. Save Saving automatically
also applies. And we have this material now. It looks like there
is a sheet of glass and you look it
from one direction, which is the point of
substrate materials. This would be very hard to get this specific effect if you were to do it with
regular materials. But this may be quite
hard on the eyes. So what we can do, let's test
it with different colors. But we have black with some, let's say, bright
red underneath. Let's go back to Well, black itself is not
much of a color, but the fact that we have this roughness parameter
here affects how it looks. So if we were to
increase roughness, let's say to one and apply this material suddenly we have a rough material. But we don't want it this rough. Let's reverse it, and we
don't really want it black. Let's do something
fancy and have two bright colors collide
with each other as such. And we have this styling note. Let's increase it even more. I want even more smaller
rocks in the pavement. And let's give it a moment. And now we have this material, which I think I'm okay with it. You could add multiple
colors, multiple layers, and be creative and obviously the substrate by itself
has multiple options. You could, for example, edit the roughness of the
second layer as well. So if you make second
real roughness zero, the second layer
will be very shiny. So now suddenly there is more
shine on the second layer, and if we reverse this a bit Top layer will not
have any shine to it, but bottom layer will be. So it will eat the shine. But if we can also do this, and roughness here can
be of a similar value. And add a sickness to the layer. So how thick is the top layer. So when we have
this top sickness at zero means essentially
top sickness doesn't exist, we will not really see it. So let's just prove a
point, apply, and see. We have a very glossy
yellow material. But if we put it into
something like one, this is too sick
to see the yellow. But if we dot zero dot
five, still too sick. Zero dot one. Maybe
it's still too big. The logic here is too sick
to see through the object. At zero.01, you can barely see it and barely see the yellow. And if you reduce a bit
more, bet I mean ten times. Now it's all yellow. You could
just put it at something five and you can adjust how much you want
the material to be Cro. But it should be
very small number. Sadly, unreal doesn't
have a documentation on how small the default
value should be, but we can just test it out and take a look at it as
we are twiging around. 02 is too thick, and maybe we should
have a value of seven And again, we could also disable it and
see the difference, as you can see, bit more
yellow, bit more blue. Sadly, I'm not aware of what's the default
sickness of it, but I'm going to assume
it is somewhere 1-2. Most likely one.500 15. Yes. Something along the sides. I want it to be more yellow, so I'm going to put it at 05. Apply. Take a look at it. Now, the blue and yellow
is not a good combination, but we are going to leave it
for now because I want to test and show you how it looks with a
different normal applied. So second layer we
have essentially looks like a layer of
rocks because of this normal we have here,
normal texture. But we can also add a
texture on the first layer. So if we put this here
and plug it into normal, my apologies, we
need a texture node. We put it here. And let's add a different
texture node so we can just search for N.
We don't want clay. Is there any interesting normal? Let's take a look at rust. Rust as a normal texture. Let's apply it. We may
need to add tiling. Now we have this weird
rust thing on top. I don't like the tiling of this, so we are going to
add a texture node. Let's dentitize this
as well. Apply it. Rust node normals
may not be the best, but suddenly we have these
imperfections in the material. It feels like a
block of water is frozen above the
cobblestone pathway, but the pathway itself
is also layered. And all of this is done
by simple material. If you were to just
remove this material, it looks like a block stone. But here. Now, what we can do is instead select something
that would make more sense. With a cobblestone,
basalt normals. And let's change
the colors as well. Blue is not a good color. Let's make it something like brown brown color mixed with Let's see. Let's make a color
to colour material, apply this Perhaps
it's a bit too bright. Yes, this is a bit too bright. So let's reduce
the saturation of it and have it a bit
darker, maybe a bit more. You can pick the
color this as well. Let's take saturation
and put it below. They are very similar to colors which is completely
fine for our purpose. Yes, this should be fine. This now looks like color
scheme is not that far off. We could make it a bit more
dark on both accounts. We can, which is more important reduce increase the roughness to
make it less shiny. So let's make it that far. And this one can be
straight up one. Save Okay, now it's
much less shiny. We don't want it to be
metallic or anything. There are additional
parameters like for example, if you put fuzz roughness here
and let's say fuzz amount. Let's take a look at
them and put it into one and fuzz
roughness into zero. Let's make it one
as well and add a color. Let's say red. We will get an additional tint. But this is a bit too much, so let's reduce fuzz
amount to zero dot five, perhaps even zero dot two to just add some
redness to the material. And now we have a material
that's a combination of three colors, two normals. It has multiple
parameters for roughness. And we did not touch a lot
of additional settings here. And the there is multiple
ways you can go about this. We can add additional
vertical layer and add one more substrate slab and layer them again and
add even more normals, even more colors, even more like additional roughness,
UVs, et cetera. There are infinite ways you can use this to make good
looking materials, and Unreal has a
substrate material demo you can download for
free and check it out from their education
and tutorial section in fab or in the Unreal
Lunch, there's samples. Section that you can click
on and take a look at them. I do not believe Unreal has substrate samples in
the starter content. Yes, they don't have it, but you can download them
and take a look at them. Anyway, for now, let's say we are finished
with our scene. Next, we want to add gameplay
element in the scene. So first, we need to make
sure our character works. Let's press play, and our characters spawn in
the middle of the screen. Why? If we go higher
and press play, our character spawn from
where our camera is. The reason why this happens
is because we don't have a certain
indicator in the scene. And that actor is called
here, let me see. Character. 1 second. Player start node, this one. So this player start node defines where your
character starts again. Obviously, you can
overwrite it like in game by save files or
just some triggers. But usually, this is
just a starting point. And now, regardless of
where our camera is, our player always will
spawn in that point. Make sure to this doesn't
really is in a proper position. If you put something like this, you will fall
through the ground. So you need to make sure your player start is
in correct position to not overlap with
other objects too much. And yes, we have this now we
can do some gameplay stuff. We can move around our scene because we create these
rocks with our materials. They don't have collision, which, to be honest, we don't want in
the first place. And before we start, let's add some kind of way to climb this part even if we are not going to use it
just for visual purposes. So let's go to our
place actor tab. In the windows, go
to place actors. And let's go to basic shapes. I believe we had a
stair somewhere yes. Curve sir lines sir.
And let's use this. This is a brush mesh. So this is not really a mesh. It's more like a modeling tool
combined with static mesh. And you can just increase
the amount of steps it has. Let's increase the height for 80 and number of steps
to, let's say, 50. Oh, I may have overdone it. Let's say number of steps
should be something like 35, 32, one. Make it. It should be fine. Maybe let's make it wider. It's less of the scene. And let's use let's
just keep it Lexis. And after we have
aligned it as we want, we can create static mesh, and let's see, keep it
in the generated mesh. And now this is
converted to mesh, and we can use our material, which we used here, you
can just click on Bowe, click on this mesh, and click on Use Select asset
from the browser. And now we have the
same mesh applied here. Because this mesh
is much smaller, the tiling is very small
as well, but it's fine. And now, in case we fall off, as I did just now, we could climb, but this mesh
does not have a collision. So we click on it,
click the collision, and we need to selet
collision preset to block all as it's a mesh. And I just wanted it. We have some empty space there. We can fix it in a second. But it still doesn't work. Now, the question may be, why doesn't this work, which I will showcase you in a second. So this is a brush. We created it from the
basic brush, right? And if you check the lit and go to player collision, this
doesn't have a collision. The reason why we
created this mesh, but we never set
collision on it. So what you can do is you
can go open the mesh we have generated and click
on player collision, and there is nothing, and click on the collision
bottom on top to create one. So there's at sphere collision. There's capsule, there's box. So if you click on the
box simplified collision, this is not ideal. So just to demonstrate
how it will look, let's move our play start nearby so we don't
have to walk too much. Now we are moving on air. The reason is because
there's a collision, it's the shape of a
box underneath us. And that's not ideal
for our purposes. Just a general
rule, keep in mind, the only things you can touch in the scene are scenes
that have collision. Unreal generates certain
collisions by default, assuming you will need them. But there are certain
cases where like this, it's not being generated because this is usually
used for prototyping, not actual layout of the scene. Now, to make a proper
collision for this, ideally, you would custom create it in a modeling software
or just move around your collision by yourself
using some tools, modeling tools, et cetera. But instead, what
we are going to do, we are going to remove our
inefficient collision. C on the collision and
convert bookis collision and We will click on
Oto box collision, out convex collision,
my apology. And on the right side,
we select the quality, and we don't really care too
much about this quality, and we will click Apply. You may want to reduce certain collisions until
but now this is misshaped. If you make it very low,
this will look very bad. As you can see, this is
not even a full collision. So let's just put in
defaults and pre supply. This is not really ideal. As you can see, there are
extra vertexes, et cetera. There's collision lines
that don't make sense, but this is just for
prototyping purposes, so we can just
leave it as it is, and now we can move around. Now we have this ladder,
which, to be honest, we are not really
going to use because I intend to encompass this whole
area with a collision box. So player cannot just
jump out of the layer. A lot of games, you
may remember if you're a proficient gamer has out of bounds areas with
invisible walls, et cetera. And the reason why it is done is the developers don't want you to go where you are
not supposed to go. For example, in this case, I'm climbing this mountain and if I go beyond
this mountain, there is nothing there,
and I will fall out of bounds and when I reach a
certain point in the map, the actor will get destroyed. I will be infinitely stuck
in a following animation. Obviously, this is not ideal and we don't want
that to happen. So usually we add
invisible collisions, so you cannot move outside it. Again, this can be easily done, going to place actors and
we can just search for it by typing blocking. We have now blocking volume. So we add this
drop to the level, can remove our play sectors. You could also click
here and go to volumes and go to blocking
volume or just search here. So we have this
blocking volume now, which all we really
need to do is size up scale up to be more precise, and let's do this. And just for
demonstration purposes, I'm going to make it very big in all sides and put this
invisible wall in the middle. So let's press play, and let's try to go into
the middle of the scene. You may see something familiar. I am not able to move
beyond this point. Visually, it does
not make any sense, but there's a blocking volume here that's preventing
my movement. So what we need to do instead, we will just shrink it down, make it longer, and put it
so it encompasses the level. The easiest way to do we can use player collision to see exactly where player cannot
is not able to move. And we don't want the player
move any further than this. Let's make them more bigger. And we can shift out clicks
with all the way around. We can shift click this again. Rotates is 90%. Nice. Degree and shift out again and move
it all the way here. And now, while this may look like one key because they
are not perfectly aligned, to be honest, they
don't matter as much as we are not
going to see them here. Obviously, you
would want to have your collision boxes precise. But for prototyping,
you're seen, you should not really
worry about it. On the topic of prototyping,
during the game development, it's very important to prototype and test
their games fast. In most cases, the reason why game is released
and it's not fun is because it was not prototyped and tested properly
at the initial stage. And when the developers realize their game
is not actually fun, they are met with a choice. They need to either continue developing the game
that they know is not fun or they try to
somehow make it fun. Or they just push through
and release it as it is, or while the most ideal
from the standpoint of, you know, morality, they need to restart
the whole project. So the best way to know if what you're making is fun
or not is to make a game. And to make your core
concept of gameplay, even if your models
look like nothing, what you need to do is just
use what you have at hand, make a fast prototype of
what you are trying to make and make it into a game. So what we are doing here now, we just have a random
environment with some random foliage and
debris, et cetera rocks, and this very
random, most likely, in opinion of most people, very ugly platform that we're going to use
as a gameplay area. I'm trying to make sure I
use every chance possible to explain the additional
functionality of the tools available
to you in the scene. As such, we are going to
do some things different. We don't want it
to be light time. So what we are going
to do, we are going to control L and make it darker. I will make it
even darker later. We are going to add
light sources on top of here on all these lines. And these light sources will act will be our main
sources of light. And this will be
mostly visual element, and the light color will change depending on
what we do in the game. So my idea currently
is very simple. We're going to have some
physics objects like spheres, and we're going to
push these physics objects into a certain part of the arena that will move around. And your goal is to
get certain amount of balls into the arena, and after you are
done with that, you are free to go
for this platform. And this will be the
end of our game. We are going to have
some interactables. And we are going
to have a gateway here where our ladder is. And most likely we
will add some walls here to make sure
you cannot really go out without overly relying on the blocking volume that's just straight
up blocks here. We are going to add some
framework, essentially, and we're going to
add some doors here, something that
functions like a door, like something that's
gate or a fence. Yeah, fence is most so now let's discuss
what we need for this. We need a light source. We are going to reuse our previous blueprint
with some differences. We are going to use
a fence to just add an illusion that say
have a collision and it's blocking our
movement outside. We are going to use
props we have at hand and we will need
physics objects, which will be regular
basic shapes like spheres. And we will need to create
some blueprints to move around our zone that is essentially
going to act as a gate. You need to score points in. And this is going to be basic gameplay
concept of this demo. Sentially this is a very
simple prototype game we are making just
to see if it is one, which is most likely
the most important part of the game development to see if you can make something fun. While I'm showing you
how to do all this, you are not forced to repeat
my step step by step. You can create something
fun straightaway. I'm trying to make
sure we can learn as much as possible about game development process
in the unreal, well, also trying to not
waste too much of your time. And to keep in mind, these
are all bare bone basics. Every single element
in the unreal is very complicated if you
dig enough, dig deep enough. Instance, the way light works, how the shadows work? How the material functions work? How can I create materials
that move around? Imagine every single game you have ever played
or seen in your life. Every single even
relatively simple stuff in the games, logics, functions, if you try to implement
it in a game, suddenly, a lot of points that pop up that you have no idea
how to do or how they work. The most important thing
as a game developer to understand how gears
click together. How one object
interacts with another, how a material reflects light, how shadows work together with
the light, how landscape, the meshes, the static meshes, the characters all can
interact with each other. How can you just open a simple door is
different for each game? Do keep in mind
how it's all done. And in the next lecture, we are going to create
our game elements. For now, let's finish
setting up our scene.
19. Blueprints for games 01: Now, let's begin by adding
some lights to our scene. I already used our
previously created lamp, scaled it up, rotate it down, and depending on your scene, feel free to do the same. Just to find a relative position where you would like
to have your lights. Now, you may take a look at the screen
and realize suddenly, Oh, there's a lot
of space to cover. I would have to manually
add this light, let's say, every hundred units or every 500 units to
cover my whole scene. You may, by all means, do that. But the issue is these lights we are going to
add to our scene is going to be there's going to be a lot of them because of the size of the scene I made, and it would take a
lot of time for me to just manually place them all. Instead, what we
are going to do, we are going to create
a function and have a construction
script that run for that function that can place
these actors in our scene. So let's do this. Let's first
of all, create a new actor. And it's going to
be just an actor. We will call it
BP light spanner. Open it, save it just in case. For visual purposes, let's add something here that can act. Let's just add an arrow so we can see what
direction the X is. If you're wondering how it
would look in the level, if we just add this here going to make default syn root, compile. We're going to have
this red arrow that shows where this
blueprint is looking, which is going to be useful. We can scale this up, so it's easier to see. The actor itself will not matter as this is just going to be used
for construction. So the reason why we created
this actor is because if we create it here in the
construction script, this will run on every
copy of this blueprint. But I just want an
actor that will spa certain amount
of light actors, and after that, I will just remove this actor so I
cannot do this inciting. So what we're going to do is we're going to go
to Construction script, and some of you may
have already tried, but if you go to spa actor from class, you may be thinking, maybe I will just click Lamp, Blueprint, and for, let's say, get actor transform,
attach it here, and here. You may be thinking, Okay, all I need to do is this. And if I go to my level
map and press play, there will be a second light. I will simulate it, so I
don't have to cool that way. Well, you are technically
correct. It is spawned. Obviously, we did not tell how to spawn, but there is an issue. I still placed only one actor and that actor is
attached to this actor. So we just did it
with an extra step. Now, your idea may be, okay, what if we use
construction script? This is what it is about. You cannot copy directly spawn actor into
construction script. This is for comp reasons, computational reasons because it can easily break the engine. If you create an actor that creates an actor
that creates an actor, so it is usually
not a good idea. Now, what can we do
to make this happen? We cannot use this, and we cannot use this because we
don't want it to be in game, we want it to be before game. And construction script happens before the actor is created. It happens before
beginning the game or even doing anything
in the gameplay. To do this, we need
to create a function. So let's create a function. We will call it spawn actor. The somehow managed
to mess it up. And we are going to go to construction script and
call spawn actor function. And we will copy this and put it inside our
spawn actor function. No here. Span actor. We're just going
to do it like this for now, Compile and go
back to the level, and you may see, wait
nothing happens. This is because this function is not something that should be callable by the construction script
in the first place. So what we're going
to have to do, we're going to click
on spawn actor and click on call in Editor. This means this now can be called before event begin
play during the editor. So we're going to go back. And we have this actor
selected light spawner. And we have now a button
called spawn Actor. You click on it, we
have actor that spawn. This is exactly
what we need, and you can just now
move this actor, click once again
and spawn again. Now, this is still not
exactly what we need. But first of all, let's get value or resist
rotation and scale. Here we need to make sure we get the right values for
the spawn actor. So actor we are trying to spawn. To understand how it works, first, let's take a
look at this node. This node is called
get actor transform. Transform means the rotation, location, and scale
of the actor. In this case, the target
for this node itself. So it means it is
getting these actors. By this, I mean, this
arrow actor we created. And it is getting its values for rotation,
location, and scale, and we are putting it
into this new node here, which is creating the lamp node with the parameters descent. So it is essentially copying the exact same values
from the actor itself. But this is not
always what we need. So in this case, particularly, we need to edit it is
rotation and location. We can keep scale
as it is because the default scale for
this actor is five, as we have previously
set up here, and the scale for the
lamp is five as well, so we don't really
have to change it, but we could do it from the
function here if we want. First of all, let's
split struck. The reason why we
do it is because we cannot edit all
these nine values at the same time easily. So we split them, and we now have
individual parameters that we can attach
to each other. We can just put in
scale as it is, but we need to modify our
location and rotation. So what we can do for rotation
you may want to Oh, okay, I will just add the value
I want on top of it and maybe even just plus. But you may notice this
doesn't work with rotation. If you do it with
vector, it will work. Now, the reason is
because rotation is usually not just a value. So actors rotation is in degrees and not actually
float values, usually. So what we need to do instead, we are going to put
this here as it is for now and we will further split strtin and we will spit strtin
here as well. So if you take a look
at our rotators, here we have a -180
rotation for lamp and 179, well, which is actually
just a float error, 180 for our Z. But if we move our actor
here and let's say, rotate it 90 degrees. Now it is 90, 180 So what we want it to be is
we want it to be -180 always, but we want axis
to be modifiable. So what we are going to do, we are going to keep Y as it is. No real reason to change it. And for X, we can just
put in the value of -180. As for Z, we are going to add And what we're going to add here is,
let's take a look. If we were to revert Z, this will look up and
we need to look down. So make it 108. I may have made a mistake, but we will know it soon enough. So let's take a look at
it by going to our level. That's for now. And click on
this and clic on Spawnctor. Yes, I have made a mistake. You may notice this
is incorrect value. It's 90. The reason is because the default
value for this is 90. So I should have calculated the difference in
between them instead, and for 180 and 00 hundred 80. So for it to be exactly
way I want it to be I would need to
rotate it extra. I need an extra -90 degrees. So let's do it -180 and
see how it works now. Again, this is not correct. We are getting the correct X, but we are not getting
the correct rotation here because we are adding
the -180 on top of. Let's try -170. Compile, and let's try now. Let's remove this
one and spawn actor. Now it is as it should. So the issue was we had positive 90 degrees by
default on this actor, and we need the
difference between this and this span vector to be 270. Now, let's go back and let's try to make
use of this actor. So if I want all actors
to line up with this one, I need the aces for
this and put it here. Copy paste. And
let's try it now. Yes, it is more
or less the same. Now, to make sure our other
excesses are correct as well, we will just copy them and place them until they're on top of
each other and after that, we will just move it around. Now, their origin
points are the same, and we can now move it
and click Span actor. Now, it's just span sector, and it's full of functional
actor that we can use. Now, it is still not
exactly what we need. This still means will
technically a bit easier than dragging the required actor
every single time, it still means we need
to drag this arrow all around and
repeat this process. There's a way to
make it even easier. So now that we can spawn this
sector anywhere we want, let's put it all the way here as the origin point and modify
our blueprint further. You may have noticed we have this transform location node. So if we put in
additional value here, let's say this is on
Y axis currently. So if you put additional
Y axis like let's say 500 units and press spawnctor
we spawn it 500 further. Let's say we want to spawn
500 a lamp every 500. Units. Now let's take a look
at our blueprint here. We have this here
that's responsible for our Y location, Y axis location. And what we want it to for the first actor being
created, be at 500. Second one be at 1,000, third one at 1,500 and
so so, so on and so on. That means we need to add 500 to this value each time it repeats, but also we need to add some kind of limit to it because we don't want it
to happen infinitely. So what we can do here, we can press N key and
click on the blueprint. This will create this
node called D N, meaning do certain
amount of times and that certain amount of
time is this value over here. We will get this and put
it into a very start. And this is going
to be our counter. What we're going to do is do it, let's say, for now three times. And each time we do it, and the integer is going to be obviously zero,
one, two, three. The reason why it begins with zeros with the integer and
integers begin from zero. And we need to make sure
we edit this value, right? So we are going to
split this structure, and we are going to get
this value multiply by 500 and put it here. What's happening
now is depending on which iteration of
this process it is, it will take this value, multiply it by 500 and
place this actor in the value of that location. So let's go back to the
level and see how it works. Let's remove this lamp first
and click Spawn Actor. Now, you may notice this
is not working correctly. Because we don't have
this going back to the. This spa itself
does not repeat it. You need to have the end of This just limits how
many times this can happen. So what we're going to add, we are going to add a re root
node here to make it clean, and we're going to put it
back here and we're going to move this to have some
sembolans of organization, which we can use more
of in this project. And now we go back, compile, and let's remove
this now and click Spactor we have now if you take a look at
location value here, the difference is going
to be exactly 500. Now, this is exactly
what we need. Now, we just need to have some kind of calculation on how many of these
actors we need. And let's say, I'm just going to eyeball it and
let's say I want 15. I can just click 15 here, compile it, save it just
in case save it as well. Spawning multiple actors can
crash your PC depending on your logic you have put in and your PCs specs, spawn actor. And I believe I
bolded correctly. Yes, now we have
15 lamps with one. There is some shine
going around from the lights we created because
of the materials we have, which we will fix all later on. Now, we want this to repeat again but this
time on other walls, and we can just take this
actor we have, move it around. And now this time we will put it here all the way
on the left side. Now, when we click
this bottom again, we will have this spawn
in this specific line. You may be wondering, Okay, why did it spawn
this way and not in the same direction as
arrow at the previous time? The reason why this happens
is because while rotation of this actor in the blueprint we have created,
we control theses. Is from the actor transform. We are forcefully adding transform location
in a different axis. We are not really using any directionality
on where it should spawn. We could make it happen. We could get the actor's
current rotation, get the arrow's rotation, for example, and put
it in as a value. But all we are trying to do here is to do
them in a straight line. And this green line is Y axis, and blue one is Z, and red one is X, and our big red
arrow is on the X. So if you want to
spawn in the X, all we need to do is
really just put it here, compile, and press spa nectar. Now, the placement of
my arrow is bit flowed. So let's put it like
this right again. Let's see if they look
okay. They are fine. And now what we can do, we can just move it all
the way over there. Now, we need to rotate this and make sure you ignore
the light fluctuations. This is because of the skylight
and exposure settings. And now, again, we need
it to happen on Y axis. But this time, If
we do it like this, compile and click Spawctor,
it will be reversed. The reason why this happens is because we have a
positive value and we went from the positive
Y X to a negative one. My apologies from
negative one to positive one, higher value. So instead, what you can
do is put a minus here, compile, like spactar
and now we have lights. Obviously, they're not placed
correctly at the moment. Yes, much better. And now we do the
exact same thing. Again, we move it around. The reason why
we're rotating this and moving around
is because we are getting actual rotation from
the rotation of the actor. This way we don't have to re
rotate it every single time. And now we will spactor again, and obviously, it will be wrong. We need them to be
in the X axis now. So what we're going
to do as before, we are just going to
move this from Xxxs and if we try it again, well. So by making a
construction script once, and I believe I misplaced
these lamps slightly, so I have to manually
put them down. Oh, no, I did the geometry a bit wrong.
It should be fine. We're not striving
for perfection here, we're just in a prototype. And the best part here is of making a
construction script, just a spa actors as we did now is the span actor itself is not necessary
to remain in the level. We can remove it from the level, and we have all these
blueprint actor lights set and now we can adjust them. So before we do that,
let's select all of them. And I would like to add
them all to folder. Lights. And now we can just go
into any blueprint. Sorry, not any blueprint, click on any lamps blueprint, we jump straight into it, and we can now adjust
the spotlight. So let's adjust the values. We could make these values editable and do it
from the editor, et cetera, but we can just
do it also programs here. So let's do it. Let's see how it looks when
we do it this way, compile. Because we have a
lot of vectors, it may take a lot
of time to compile. And let's reduce the cone range. I want them to be like
spotlights and make it 30. I want it to be 30 as well. Compile. See how they look now. I would like to rotate
this spotlight a bit so select this spotlight specifically and rotate it. Let's see the faces
here this way. So when you seven degrees, compile with the
moment, I don't want. I believe we have
extra light here. Remove it. Just to check if they have any extra
lights here. We do. And now we have the light setup perhaps even a bit more 60. This slides now need
a bit more radius. So let's make it 35. And as for a adhesion,
let's make it 35. Inner core can be Let's just one. Suffering can be 25. Compile it, go back. This is not what I
want from the cone. Let's go back to maybe 25
and 2,500 should work. And now if you play, there are different colors, and they should change colors
because this is how we set them up in our
previous blueprint. Now, let's take a look
at our spotlight, and I changed my values for
15 15 in 2004 autentation. And now we have
this result where we have spotlights,
these colors. And now what I will try to do is to move them around as
they are moving the scene. But before that, I do
not like the fact that our material is this color. If you have moving
lights around, I would like to have my
material a bit darker. And perhaps this is a bit
too dark in the first place. Let's make it a bit brighter
but not that bright. So we can see everything, but not have some
blinding our eyes. I don't want shadows
from the sun, so let's move it around till we get to position
where we're happy with. Something like
this? No. This kind of thing you just tick around until you get it
the way you want. Yeah, this is much better. Now, I don't want because we will have a lot
of color for lights, I don't want the
colors to clash, so I will make it
a darker color. And let's I put the roughnes to one because I don't want the material
to shine too much. Let's do it a darker color
for the let's you know, let's do C blue. Let's see. Dark
blue. The first one. The second color
can be much darker. Perhaps you could
do it even darker. Save it and take a look. It's fine. And now press play. Now we have colors that
are quite easy to see, and now I want to move
them around slightly. So we're going to create
a new function for it. And let's do it here
with a timeline. So what we are going to do here is we're going to
create a timeline, and we're going to add
a sequence node here. We'll have a sequence. We're going to do this once, and we're going to add a
do once node. Do once. Wait, apologies. We don't need do once.
We just need timeline. Time Yeah. My apologies. I am not sure why I have
to search for it so long. But let's do it like this
so it's not in the way. We are going to have a timeline. And this timeline, we are
going to play it from the start and we are going
to after it's finished, we are going to a
delay of, let's say, 1 second and we will Play it again. Now, we will do a play. So the reason we are
going to do this, we're going to add a track, and we're going to
add a vector track. And we're going to get a bit
creative with the timeline. So we can we have now Z, X and Y, and we're going to do something
quite a bit different. We're going to create a
variable and we are going to randomize these
values the timeline.
20. Blueprints for games 02: Now, if we take a look at this
timeline we just created, we have some vectors
we can put in here, and we can transfer
these vectors to our light spotlights rotation
to move around the lights. But because this is just
a set of values you put in they would be the
same every single time. So every single time
timeline would finish. We would play from the start or where it stopped last time, and it will begin again. This is not what I
want for this level. I want lights to move around a bit in a certain directions
randomly and go back. So we are going to change
the way we use our timeline. We'll open our timeline, and we will remove this
track we just created for verte vectors and
add a float track. And this float track will be between let's say for now,
let's keep it as it is. We're going to call it Alpha. We're going to compile it, go back to Event graph. And now we have an float value that goes nowhere at the moment. We're going to do it Let's
put it into Let's make it. Lights rotate for 8 seconds, and in 8 seconds, the value will go from
unity shift clicks. The value will go from zero, 28. Eight second. Eight second mark, we'll go to eight. And let's make sure we
have it correct set up. Yes, we have it's
correct set up. So we shift click it
at the keypoint at zero time value zero to
at 8 seconds value one. So now this Alpha node here is letting us
put the value 0-1, and the value will
go 0-1 in 8 seconds. Well, let's remove this
lines to keep it organized. And we're going to add
a arp vector node. So arp vector. And we're going to put
in our Alpha here. Now, to explain what arp does, arp function essentially
goes from value A to value B gradually depending
on the Alpha value. Alpha is usually a value 0-1. And at zero, it is
A, at one, it is B. And this is useful when
used this timeline to gradually change the location or rotation or anything really. You want to do over time
without using eventi. As eventi is, first of all, will not be as
smooth as using LAP. And secondly, it's
more performance. So we're going for now, test it, we're going
to have a value. We will play from start and we will print string this value. Oh, no, we cannot predict. We have too many
lights in the scene. So instead what we
are going to do, we are going to move the lights. Now, we need to get rotation, but by my mistake,
made a larp vector. Let's fix this arp
rotator instead, as we're going to
work with rotation. And we're going to get the
rotation of the spotlight. Get not get sorry, my apologies. Set rotation. Set relative rotation, I believe, is the correct one. The difference between
a relative rotation and a world rotation is the rotation relative
to its parent would be the rotation of spotlight
relative to static mesh. But world rotation would be it is rotation in the world itself. It may be a bit complicated
to understand right away, but it is just what it is. You need to test it out the differences as
you use unreal, so we will put this here. So what this will do, we will
get a value between zero and B and the Alpha will do
it for us, slowly rotate. Now, for now, let's
put in fixed values. The spotlight value
currently is 90 Y, and rest of them is zero, zero. Let's say we want
this to go 90-30. We'll compile it, save it, go back to the level
and press play. Nothing is happening. Now,
the interesting question is nothing happening because
we are not changing the value or Interesting. Let's stop. Yes. The issue is the spotlights
are currently not movable. So let's go back,
click and movable. Now this is more
computationally heavy, but for what we
are trying to do. Now we have spotlights
that move around. As they disappeared because they don't have enough radius, we can increase that
radius quite easily. So let's go to viewport. And currently we have 2000. Let's make it 8,000 for now, rest compile, go back. Let's see how it works now. And let's see how lights
are set up currently. So we're getting
this weird light. Again, it's mostly because
of the way it's rotated. Now let's take a look at our lights and see why this weird artifacts
start happening. We don't get proper shadow. So when we rotate this,
the light itself, it's a fine, but we
are actually rotating the blueprint spotlight only. We don't actually
rotate the lamp. So when we do this, we get a cutoff and the
reason for that cutoff is because the light is
colliding with the mesh, and it's giving us
this weird cutoff. To prevent this, we can modify
light channels, et cetera, to not collide with
the light of mesh, ignore it on light channels, and perhaps we can even create a new mesh that
doesn't give us this problem. But the easiest way to do
fixes is to go spotlight, move it a bit outside the
mesh, save and prespy. And now, We will have
this kind of range. Now, it's fully covering
the whole area, which is exactly what I wanted. But we don't want this to happen every single time
exactly the same way. What we're going to do now, first of all, I'm going
to organize this a bit. I did not like how
cluttered it is. And we're going to have this lenode and we're
going to move this all down. Spotlight here. Now, value we get from
that we put in forcefully is original location or
rotation of the light, which is 90, and we reduce it to 30 to move
it around the scene. But if we wanted to
give the wider range, we need to also
change other value. So if you put it like
this and increase rotation on the Z axis, we can also give it left
and right movement. So let's look now, the rotation we
would like to give it is between 90 and -90. So we have a range of rotation. So what we can do, we can
give a Z minus rotation, for example, and P 90 rotation. Again, this is not final. I'm just doing it
for a demonstration. And if we press play, we now have rotating lights.
21. Blueprints for games 03: We have our light
here, and we want to replace all our references
of this with this. So what we can do is we
can go to our lamps, select them all, right click and replace selected
actors with BPight. Can copy properties
or ignore them, we are going to we're not
going to copy properties, so we're just going
to click this, and we are going
to replace them. We will give it a second, and now we have all
of them replaced. They're all scaled
up with too much. So let's scale them down. Let's do a scale And now all of them
are scaled way too. I also would like to make them a bit yes, let's just put some of it
down and let's change. No rotation, reset rotation. Also, let's rotate 90
degrees -90 degrees. And now we have all our
lights newly replaced, and we can test our
cube logic again. Let's put it this way
and reselect our lights. And we can just click Target
and target this cube. Press play. Nothing happens as we removed Even tick from this. Let's just add it for a second. Rest it, compile,
save, save as well. Now, all lights in our
scene follow this cube. Which is quite nice. Now, we are going to leave this eventiq these
notes alone for now. This is our function
to follow the target. Let's add them all
under one comment. Follow targets. We're going to keep
it like this for now. And we're going to go back to our lamp blueprint and start
copying some functionality. Let's remove this as
we don't need it. We will need this for
random lights as such. Let's use this. I do not wish to
use array for it, as I will use random integer, float values for it instead. So I'm going to copy
this and put it in here. If I compile, I will
get some errors, create variable, create
variable again, compile again. Now it's work as
it's supposed to. And now we do have a spotlight, so this just gets value from our spotlight here as
they share the name. And let's just test this
and see how it works. From the start on
event begin play, there is no value
here currently, so we're going to add something
soon, let's press play. Nothing is happening. Not really. The lights are just looking in a
weird location. So let's do it flex this. So it's supposed to
be -90, let's see. Our lights are Interesting. Oh, if you don't have it
attached to Evan's begin plate. My apologies. This is
not the correct one. I keep mixing up the lamp
blueprint with a new one. Let's way. It's still not
working as it should. So let's take a look at it. Went play timeline. And in the timeline, we are doing something wrong by going straight to this value, we were supposed to go to
set relative rotation. After that, going to
that value let's play. Okay, now they are
looking all down. We don't have random colors
or whatever set up yet, so we are going to
fix it in a second. And we have our
timeline, our delay. This is unorganized too much, and it makes it more
complicated than it should, so we're going to
organize this a bit. Let's change this
whole placement of it. Let's add a comment on
top of it now and call it random mover but. We're going to compile this, and now we have it organized. We're going to split
this structure pin, and we are going
to randomize it. Random slot in range. X, as we found out previously, doesn't matter for
lights too much. Mm. Now, let's look up our values. What? Let's select the spotlight rests values just in
case we might as well select all blueprints
as they may have check actation is
correct for all of them. And we will make
sure our spotlights are Our spotlights here
a weird rotations. Let's fix them as well. We
fix it from the blueprint. I will fix it for all of them. So just make sure we don't
have weird random rotations. Let's click on the spotlight
to test it and take a look. Y X clear as the XXs
matters as well, and Z will matter when we
are taking it from scratch. So all our Xs matter in
this case, as it should. Now the question is how much is the range we
want them to have? So let's say this is I
don't want the lamp to have more than 40 -40 or zero. Now, -90 and 40. So for Y axis,
which is this one, minimum should be -90, MX should be -40. Let's restore it.
For our X value. Again, let's do 40 and -40. I don't want it to have
too much of a range as it causes the
lights to blur into each other -40 and and as for Z axis, it's 180 degrees pretty much. So let's do -90,
still positive 90, it's just gradual rotation, and we want it only on one side, so we're limiting the range. So now, save everything
just in case, spy. I got lights moving
around randomly. See what's going on with
our spotlights here. We have two. Let's
see, make sure. This is a value of zero
at the moment, light, spotlight and such This is zero, and it's -90 and plus 40. Did we make a mistake with YXS? Minus oh, oh, this is the issue. -40 to -90. I made a mistake
of putting weight. This should be
correct, I believe. The number we want is between -90 and -40. Let's test again. Interesting the way they
move outside the radios. Z is fine. X. It's fine, as well. I am guessing it's
a combination of three randomized values
is creating this issue. So if you put X into zero to No, zero, not. So let's maybe make sure we
cannot even get into -90. Let's make it minus let's say
zero. Zero may be too much. So let's say minus and
get a value that's Okay. The reason why some of
the lights start going outside is because of the way Spotlight is
getting their numbers. So if you copy this
number, paste, and click on Spotlight
and paste this number, we are going to get
the same value, and X value is not the reason. The Y value is. As you can see, now we copy this value because unlike
previous light actors, these actors share the
way they are shaped. And the way we implemented
our actor this time around makes it difficult to go outside using the
same parameters. So what we need to do is
we need to manage Y axis. Let's do it this way. We have X and Z axis
for our Shenanigans. So if you put Y axis to 50, for example, I'm sure it
will not even work properly. Our spotlight is going 50, which is 50 all the
way up in the sky. So let's make it -50. Compile and press play. Again, -50 in this part of
the scene is all the way ups. The only way we can
really fix this is by going to our
spotlight here. We part. We change the rotation to zero, we will have it looking upwards, which is
not what we want. And if you remove
it from the mesh itself, compile and reset. Now, because we removed
it from the static mesh, it no longer takes
in the rotation of the static mesh. So
now they're at zero. So let's try it now. Now we have the issue of them going only on
negative direction, so we are going to go back to our spotlight and see
the values we need now. The value -60 in
this side is inside. And if we look at this location, now, positive 60 is inside. We don't want it
to randomize too much and go out of
the bounds on Y axis. So instead what we can do is we can do a value in the middle. Two axis and have it
minus cert and cert. We will compile this and play. This will have. While
there will be some lights that go outside just because the way the randomizer works. This is fine. We are going to
reduce the value cap for all of them as we don't want them going out of
the bounds too much, and I will even reduce
this to 20 and 20, as I would prefer
them to remind inside the x is fine as it's just rotation on the
hundred 80 degrees. And we will have this
weird lights going around, some of them going
out, which is fine. As you can see, they're
just going around randomly. Not the most ideal solution, obviously, but it is fine. We could also add additional functionality to
make them target only this location
in the middle, but that would require us to do a lot of complicated
vector maths, which we are not going to do. In this case, we could
also make calculations based on the forward vector. So for example, we could make them calculate their
forward vector and only aim in the location
where they are looking at, but that's not what we're
going to do in this case. Now, let's test this. We have our cube selected, and now let's get
event B and play. And here, let's for now add event tick and see
how it would work. And it works as it should, other than this one
light, I believe, and this is because I
modified its light settings, and I forgot to put it
back this one as well. Make sure to keep in mind which
actors you have modified. Have this modified, which
was not working properly, and this one, which was
not working properly. And now, everything
should be as it is. Now, we are essentially done
with random light placement, which is fine for now. We are going to add
a sequence here, and this will be 01. For zero, we are going
to add our random color. Let's go and begin
play and on zero, we had this random color
change function enabled. So we're going to copy this
and copy it back here. When you are copying function, they will ask to
create or do nothing. We create it and we
will have this on top. We're going to put it here. Remove this note for now. We have this first and
we have our branch. We are going to create this variable as we
will need it later. We will change the
name later on. And we have this random
color functionality built in and compile
just in case. Let's make sure our variables are named correctly. We have The rotation with relative rotation,
we have target. Plants are not necessary. Compile, and let's take a look
at our random color node. And let's take a look at our
random polar function here. We have this, which we
are just going to copy. You could probably copy everything and put
it back here scale. Turn out, remove back in. We're going to create
this variable, create variable light color. Compile. Go back to light
can change color, set light color, Poppy,
go to be polite. That light change function,
that light color, pop pile that is
going to put its. Now let's test it.
And it is working. And we have random color change every few seconds as
we had previously. The lights going out of
bounds is while annoying will not affect our gameplay as
much because we are going to have additional
light functionality, which makes light
follow certain actors. Now, we had this functionality here for open door
closor as well. We're going to copy this, but we are going to repurpose
it later on. Change function and we
could not copy delay. We can just add it ourselves. We cannot. My apologies. We cannot because
it's in the function. We will need to add ere. And let's comment
this section as well. Random color. Let's make it purple.
Tesaro random color. And we have now open door
event and closed door event, but I'm going to rename them. One of them will
be target located. The other one be Target score. And we're going to
change this is two. Let's see what would be
the correct name for a target being Target spawned. Called target spawned. And we're going to have this. For now, we're going
to leave it at this. We're going to later
on repurpose this now, we have our system for light. Let's go select a
Speedbard, press play. And from first person
view, this looks fine. There's some light going
around in the scene, and we have our
cube in the middle. One of the things I want
to do now is for light to target our character when the character
is moving around. So we're going to add an I node. And if the target is nearby, the light will follow
the target player. And if the target is
not close enough, we are going to
randomize the light. So if you remember
this target we had, let's remove this target
node from here now. Or to be more specific, we need to add a set actor
node, set target node. So let's set target node. And we are going to set it
to we need an input here. We are going to set
into player character. So for now, let's
do this this way. When events begin
event play begins, we are going to set
it into our target. Event tick will make the
actor's rotation follow. Or now we are going to
remove the timeline. And press play. So game begins, we get all lights focused on the player character.
This is not we want. We want only the closest
lights to be between, let's say, closest 500
units to follow the actor.
22. Actor Interactions: Now, the way you calculate
the distance between two actors in the three
world is by vectors. So what we need to do for this is let's get player character. We have it here. So let's
just for now copy it. And we will get actor location. Copy this again,
place this and here. And we're going to subtract one from another and get vector. Oh, we don't need
vector vector links. So let's for now, print string this value. And let's put it
into a ventiq now. Compile, save, res play. Oh, my apologies. We need to make sure we put it into the string,
not the duration. Compile, press play. So as you can see, the lights are
calculating the distance between the character
and themselves. And the closest unit I can
see here is like 1,400. Now, what we can do is we have
this value we are getting. And if this value is less, h then let's say 2,500
or even let's say 2000. It is true if this value is
lesser than 2000 on eventi, let's do it this way. If it is true, we will have the lights follow the
character press play. Now you see we have lights
that are following us, and if we move around,
the closest lights follow us instantly. And when we go out of the range, as distance becomes now
gives a bulling value falls, it's no longer following us. Obviously, we don't want
it to be instantly on us. We will use a timeline
for it in a moment. But for now, this is fine as we're just testing
the targeting system. Again, I'm noticing
we have a light here which I twix values. We're going to restore
this, save it, and another one here. I'm not sure why I
tweaked so many values, but this is what it is. Make sure to clean up after you edit the values
for testing purposes, and don't do it like me. Now, this logic works. We can get the location, distance, act
distance to be clear. But we don't want it to be
on Aventi This is fine. And what we need now is a proper follow
target functionality. We are going to expand this a bit and have everything inside, and let's add some extra
space so we can work. Issue we have now is
when should we get this check and when we should start getting the
rotation and how? We don't want to do
it with the eventi, as it's very performance at. Instead, what we
can do is we can check it instead of every
frame every few seconds. And the way we can do it easily, we can do it then the sequence here and actually prevent
this timeline happening. Second, let's remove this. Sure. So we're going to get this around as well as we are going
to need it later. We we have these random colors which we won't always trigger, so we are not going to touch it, but we only want
this to trigger. Let's make this seconds outside if there is
no player target. So you can put a branch node here and run it
through the branch. And if it is false, we are going to have this
function as previously. And if it's true, we are going to drop this to the bottom section where we are going to follow
the player character. Now, the way we can do
this is let me put it back in the value here
instead of having two branches, it's unnecessary. Let's add a timeline. And this timeline no can
function in a similar manner. We are going to have a larp rotator. And we are going to
have our Alpha set here and find look at rotation. New rotation will be this
one and the actors rotation. In this case, we want the
light to follow full on, not only the spotlight. As such, let's change
some parameters here. We were moving the
spotlight only. But with our new light, we can move the
whole light itself. We are not limited
to our spotlight, so let's make sure we fix
this up before we move on. This relative parameter is fine, but it should be just
rotation, not relative. And we are going to
get actors location. Actors rotation. Get rotation Actor. We're going to get these actors on rotation. We are
going to apply. They're going to set it, and we are going to
at the very end, not rotate the spotlight as there is no real reason to
only do it with spotlight, we're going to copy
this again and set rotation actor rotation, and actor itself, we get a new rotation value
and we update this. Now let's try it out
again, press play. Lights are moving
around as they should. Some of them
remained on the spot because we had the branch node. We move around here and the lights we're closest
to will not move around. But the list of it is
working as it should. Let's take into a look by using simulate and
see how lights. Yeah, they are moving around. All. Okay. Now, we had an error and
this error mode because we were trying to access
player character and player actor did not exist when we were simulating,
which is fine. We don't really need
it during simulations. And here, true, let's
try it on true. This will trigger here. Our second timeline
will trigger. And this timeline
can be shorter. So let's make it 1 second. And the value for it
can be one as well. We want lights to
react instantly the player being close to show him to shower him in light. And we have this larp node, which is now calculating the actor's location
and targets location, and we are setting our target
as a player character, which is what we
are going to do. So if vector length
between is close enough, we are going to set our target After we set our target, we are going to play from start. We are going to larp our current rotation which
we'll do by justice. By setting it, obviously, we're going to set
our own rotation. And this rotation
will be used for lurk as we move
along the timeline, we're essentially doing
exactly what we did here, but with just some
slight changes. So we're going to
do this this way. Now, let's test it. PlesPlay and it is not working as it should. We have our Alphas, we
have our play from starts. We don't have our updates. This is because we did
not add this node here. We need to update this, and we should also probably, if when it's finished, add go back to the
branch node on top. Press play. Now, it is quite weird. We are not getting the proper
values, and as you can see, the lights on top are
in a weird direction. Let's take a look at
what's happening here. We are getting actors rotation
by which I mean self, and we are getting the
location between self and B. But we are updating it every frame, which is
not what we want. We want to set the
rotation or RB. We can just copy this value. And put it here. But recombine structure pin. Put the rhythm value here. B rotation value here, play from the start,
put the value to B. Let's organize this a bit more. There are too many
spaghetti codes. Return value into this. Compile, save, is play. Now, as we move around, when they are no
longer close enough, they will randomize themselves. While they're close to us, by them, I mean
the light sources. They will start reacting. Now, the issue is the lights
which are in the middle of randomized rotation will not go back to trigger and
take a second look at us. The reason why this is
happening is because the way we set up our branch node. Our branch node begins here, and our randomized lights are checking it
not every second, every 8 seconds because the
way our timeline is set up. So now we have a slight issue where we need
to interrupt this process in the middle and get
this branch node activated to check if it is going as it should or
it should just follow. The way we can do
this is we can call this another branch
in the middle here. I really don't like the way
this packet code is looking, but we will leave it for now. Sadly, we cannot turn our
timelines into functions. Now, we have this
light that is being updated every second,
every frame, actually. So after this is done, after each update, we
could recheck our branch. Let's compile and
see what happens. It created an infinite loop. As such, this cannot be applied. Infinite loops will
instantly crash your PC. So we need to come up with a way that's not generating
infinite loop, and easiest way to do it
is to get a delay node. At the very end here, get it
to trigger every 1 second. We could do it lower,
but this should be fine. And put it in the branch. Compile, play. Because there
is a delay node there. This is no longer an
infinite loop as it doesn't trigger infinitely
every single second. So now we are targeted and when we are no
longer targeted, they randomize themselves,
or at least they should. Let's see what's happening. In the center of the map, it should not be
able to target us. Let's see what happens.
Lights are now randomized. But because we did not give them a big range for randomization, the lights move around at the last location
where we walked. So they're trying to follow us, and after they
finish tooling us, they're trying to only
go in that direction. So instead, what we are going to do is we are going to edit the values the random range. And the way we have these
values, here, right, correct? We have these random
values in float range, in Y, and Z axis. But what's more important
is, like, are axis? As this is the one responsible
for to be more clear, Y and X Xs are the ones responsible for lights going
out of field too much. That's the reason why we reduce their random
float range value. Now, we need to figure
out a way to make sure what just happened
does not happen. What happened here was we
get their actor rotation, and after we set
their actor rotation, this A here became their
new actor rotation. As this A is their
new actor rotation, they are not resetting to
their initial parameters. As such, what we can do is
simply instead of getting actor rotation every single
time, or to be clear, when we are finished
with this rotation, we can run a branch node
again on the same branch. As I do not like the
way this is set up, we are just going to
we purpose this again, we are going to copy it, put a version of it down here, we're going to add branch node, and we're going to test the
same thing if it is true, if it's false, and
this is finished, when the 1 second elapses
when targeting the character. If this is false, as it is no longer in range
and when it is in range, if it's in range,
we are just going to reset everything here
on the bottom layer. And if it is false, what we're going to do
is we are going to reset the rotation for A, so it can begin from
its initial point. So initial rotation for our spotlight is
zero, zero, zero. We can do it exact same, so we can just set our rotation. Here at 000, and this should
be all we need to do. After that, we can
just plug it in here. Now, let's see how
this will work out. We have them all trigger on us. They move around, they
lose their target. And after they
lose their target, they are not
functioning properly. They're still pretty
much very high up. And the reason is because I took the rotation of the spotlight
instead of actual mesh, which we are using,
it should be -90. Always make sure to
double check your values And let's try it again. We are doing it again. The
moment they lose the targets, they should go back to
their initial values. They should not interesting. Again, they do the same. They do properly
follow the target, but they are way too much. Oh, this is another
issue we have because we change
the values later on. Initially, the light range was calculated from
the spotlight. Again, I have few spotlights here that I have touched
and I have not restored. Always clean up after your testing to not end up
in a situation like this. This is quite common,
but nevertheless, it's not a good
practice not clean up. Let's restore it. And we have our mesh
which is sorry, the actor is, which is
being completely rotated. So if you look at our
rotation minus xs, this goes all the way back. We don't want it. -90 to so we now have you can take
a look at it, as well. You have minus nine. T the original rotation
for this actor is 180. Y. I zero, zero, again, this is all issues from my testing that I have not
cleaned up previously. This one is more correct. So we have the same
situation here. You have X axis that goes
all the way negative. We have zero and again
zero. Not sure why. Kips opening. And we
have this issue here. None of this really
matters too much. As if we just simulate, we are getting a similar result to what we previously had. Now, the biggest issue is when the player
is not in the level, so what we can do is
add an is valid node. So we have what we can do is
we can add an is valid node. So if the target is valid, what we can do instead is
if the target is valid, it is not valid, we
just continue here. If it is valid, we go to branch. This is temporary, as I don't want to get the same
error every single time. We're just going to
check the lights again, make sure we are doing
everything correctly. The lights are moving too
much in certain directions. Again, the biggest issue, Z is going very high in number, while it should
just remain at -90. We're going to uncontrol. We don't need this
anymore. We tested so we need it and made sure
the issue was not. So instead of having
these very high values, we are going to have minimum
of -90 and maximum of -60. Let's see what happens now. They're moving very
close to the range. So instead, let's
do it a bit more. Let's do positive for
five. Let's play. We could also just
take the middle ground and make it 45 to -45, which will randomize it in
all directions equally. Which is fine. Now, let's play this again,
see how it works. And after the moment, they lose the directionality. They should go back
to how they should function previously. Mm hm. So let's see what's
going on here. We have our station. So the moment this is finished, we check it if we
are beyond the range of 2000 as when this is false, et's simulate this and take a look at what's
happening here. Let's select this light, which is number 28. Let's expand this
and press play. And for our debug, actor, select 26. What's happening now? This is just repeating itself, setting its own rotation
after it's finished, and the delay is created. Oh, okay, this is the issue. We never reach the finish note as this is always
going all the way back and creating this
issue where it is always constantly playing Okay. As such, what we need to do is we need to do this
delay actually happens. Sorry, the execution pin of this delay doesn't go
all the way back and just goes the correct way. So what we can do
is, so we have this. When it is finished, we have this delay, and
when we have this, we get set actual rotation, and we need to after
this all is finished, check the branch node. Instead of straight up
forwarding it all the way back, what we can do is we can
add this branch node again. And before we move on, let's properly organize all these nodes. The only way what we need to do is we need to get this
value and make it a variable so we don't have to do all of this again,
every single time. So what we can do is we can
get this into variable, make it into a variable, and we need to set
this variable. Not all of this. By turning
all of this into function, we will collapse it to function. Call it distance to layer. Distance to clear. And when we do need this, we need it before this branch. And every time we need this, we can just put
in this function. Instead of having
this spaghetti of a code, that's just inefficient. So what we do,
distance to player, drag it drop in. And we do it again here,
distance to player. This will just check the
distance to player if it is So the way let's look at it, if the distance to player
is less than 2000 units. Less than 2000. We set this value and
we return this note. So here, if the distance
is less than 2000 units, all of this happens
as it did previously. And here, after this is updated, second passes, the
delay happens, and after the delay, we get
a distance to the player. If the distance to
the player currently, after this 1 second
of delay during the update of this timeline
is less than 2000, we go all the way back and recheck or we don't
even have to check, we straight up go to branch as we already
have set up already. Checks the distance
to the player and we go if it's falls, nothing happens, and all of this just keeps functioning
until this is finished. So now let's try now again. And let's see them and press. This happens. This is checked. We wait until it's finished, which will be 8 seconds. After 8 seconds, it's
finished and restores itself. Perfect. You might notice if
you test it that your lights will
not work properly, and this is the reason. The way these functions work, they only produce this value when they are
actually triggered. And when we have the true here and we go
all the way back, if we don't check the value
of the distance to player, this function will
not work properly. And what we need to do
is we make sure we only have all nodes that come to this should
actually come to here, and we should make sure
before branch triggers, we trigger the distance
to player event. This way, we will be able
to make sure the value, which is true or false
from the distance to player function is
actually accurate. So we are going to compile, play, and go back to the level and let's
see how it works. And after they cannot find us, they go back to their
random rotations, and when we go close, they notice us and they
start following us around. Now, obviously, we could
tweak it around to make lights more accurate. Maybe you won't want to limit the range further, et cetera, but we're going to keep
it like this for now, as we are going to
change the lights, functionality depending
on the gameplay as well. This will not be actually this randomized
constantly because surrounding lights will focus on the objectives if the
objectives are nearby. Before we move on to actually start implementing
gameplay elements, let's modify our
light once more. We have lights that move around the level and we have them
go outside the level. The reason why this
is happening is because we give them
randomized numbers. As such, they don't really have any point in the map they
are trying to focus on. It's an easy fix,
especially what we have already implemented.
Stop the simulation. And we could give them a value
and modify that value by this random value to make sure we get them
in a certain area, all lights focus
in a certain area. What we can also do, we can use our already
established target get target and use this as a placeholder for
the light to focus on. So we have this logic already here that we previously created. Let's take this
and apply it here. Now, we have this final
look at rotation, and we have this random
floats that gives randomsms to this rotation value
that's being set here. What we can do is we can
combine these two rotators, which will give us a value
that's not completely random. Now let's combine rotators, A and B, and we pitch in this combined
return value into P. Now let's take a
look at our level. There's still some
randomness in the level, but they are going to
all try to focus on the light on the target. And when the target is moving
around, they move with it. Obviously we don't want
this cube to be the target. As such, what we can do is this is still
center of the level, more or less, and we can
force down this value. And what we can do is we
can copy this location. Go back to BP Lit, remove get actor location
from the target and split the strcm let's take
a look at our values here. X Why? And Z compile presblow. They will behave in
a similar fashion, but they are no longer
targeting this specific cube. They are now just rotating in the general direction around where this cube was
initially located. You could also target
the level itself, or you can also just make
this cube invisible, put it down and call it a day, but there is no reason
to over complicate when you can hard code the values, you we could do it
in multiple ways, but this just works. Now, let's organize our code so we have easier time for the next time we
actually need this. Let's convert some of the
things here into functions. We cannot add timeline
to functions. Let's do this, convert to function, collapse
function specifically. Let's call it rotation,
generation random. This is here just to keep
everything organized. And I will rename this
function. Properly. Make sure to test your
blueprints always. And if it works as it should, you can just continue on. Yes, most of the lights
are directed inwards. We can also reduce the values of randomness so it doesn't
go too far beyond what we want to this should
be reasonable enough. Let's make it 20 to 20. While random numbers are fine, having them going too far
upwards is not ideal. And now we have this
disco like effect. We ignore the
error. It's because the player is not
actually in the level. You can add an is valid node, but that will not be actually necessary when we
are done with this. So let's take this as well. And this time, what
we are going to do, we're going to collapse
into a function as well, but it's a different function, as it's a function that's
looking at the player, and we are going to select them all, collapse the function. Found player location. Just going to name it that
way. Everything is fine. We can go back to Event graph, see if we need to
organize anything else. Command sections
are now too big, so let's reduce them. Let's see. We cannot
put this timeline into the function as it's
a time related event, and there is no real reason to collapse these two
nodes into function, as we are not going to
really reuse them too much. We have them in a
certain manner here, but they are not
really efficient way of us to put into a function. This can remain as it is. These delays cannot be added
into function or macros. And now we have a
slightly more clear. We still have these
nodes going all the way, but it's fine. We could probably make it look better if we
reorganize more, but I don't want to waste
too much time here. We have our color settings here, and next, we are
going to edit them when we actually implement
gameplay elements. So
23. Blueprint Interface: Now, let's start
making our interface. Right click in the empty folder. I already created
Interface folder, create your own and call your Blueprint BPI for
Blueprint interface, and I'm going to call it
call underscore SCORE. Compile it, save
it just in case, and we get into new function
here in the interface. We are going to rename it
and call it goal score. Why did I have L? I don't know. So we have this Interface now. Let's create one more, and this next one we are
not really going to use, but I'm just going to
demonstrate how it can be used. We are going to
call it interacted. And this time we
are going to add an output node and
an input node. An input node will be, let's say, layer arctor Let's see what we can. First, what we can use, we can use such
person character. This is just going to
be for demonstration. We are not actually going
to use it, and for output, let's just add a bulling
value of something. We are not going to
actually use it. I will remove it later on. So we're going to
save this. And we have now one with output, one without output
and and let's see. Our goal score does not have an output and our
Interactive has an output. So what we're going to do go to BP Goal and in the
class settings, go to implemented interfaces on the details panel
on the right side and click here and let's
find our PPI goal score. We compile it, and now
we have this step here. It's called interfaces. Expand it, and you will
see two new options here. First of all, let's go to event graph and click
on Interactive. We have this function that has player input and
something output. The purpose of this is to create an widely available function that can be modified
in each blueprint. So the interacted function
we created can be used to, let's say we have our
inputs and outputs, obviously, and we can
in our event graphs, call this event for example, let's say, who interacted, can be this actor itself. And in the player node, we can add the reference for
the player that did this. Or you can add an
interactable event that says, for example, coins. Imagine you are using a shop in a game and you have
an interactive event, and this value says coins, which is checking how many
coins your character has. And in this here, let's say the item you are
trying to buy costs 100 coins, you can add less than node. I'm actually going to
change this bullion value here to float, just
to demonstrate. Coins. Compile and compile
again, compile it recompile. And the reason this error,
there is no value here. And let's say the coins we have is less than 50 or equals the item you
are interacting with. This will be true
or false value, that this will output
as through all false. So the input for the
coin you are getting, this is just remaining this way because we did not
save this yet, so we are going to save it. Next time we generate this
event, this will work fine. This lets us get
information or variables, et cetera from other
actors that have the interactivity enabled by interface and easily
get their variables without having to
actually cast to the actor and get their
values by getting from here, get coins, et cetera. We will not be
really needing this. What we need is this goal. You cannot drag this what you can do is
implement an event. Now, what this does, when event call score is
called via interface, essentially by a
different actor, this event will trigger. In this case, what we want to happen is to have this
event goal score. Let's remove this interact
it as we will not be using it in the light blueprint. So let's go not balls phon blueprint and light
blueprint later on. We're going to go to class
settings at interface, again, at the same interface as they're going to have the same interface
all around, compile it. We don't need to have an
on event we can play. We want to happen in
goal scroll event. So we're going to
get this and put it in we are going to
compile this save. And here in the PPG. Let's remove these things, go to event graph. We don't need this
to trigger here. We need to trigger it all
around in other interfaces. So if we go to the score and
click Call ScorR message, this will call this event in the target section of the
actors that interacts it. Now, you may be wondering who is the one
triggering this event. In our case, it's this bow. So we're actually going to just for
demonstration purposes, I'm just going to put it as we're calling this goal event, so we're just going to drag
this from here to here. And you may be assuming
this will work as intended, but it will not because we
are targeting the ball event, and ball itself doesn't
have anything to do. It is an empty actor with just a static mesh
component on top of it. But we need you to interact with this light spawner
sorry bold spawner. And for that to happen, we need to interact with it directly by putting
it as a target. But that would involve casting, which is fine, in this case, as we have already established that they will
exist in the same level. But we can also skip
that by getting all actors with interface. And the interface we
want to select is PPI goal score, and
we will put it here. So what this will do is
when this is triggered, it will check all
actors in the level, and all actors in
the level who has this interface enabled will their goal score
event get triggered. This is not recommended to
use on time based operations, if you on eventing, it will very likely crash your PC if you
have a lot of factors. And if possible,
you would like to directly target if it
is an available option. And actually, casting
may be fine if there is a guarantee that they will be in the same level as we
have established here. Now, you may ask if
that's the purpose, why are we doing this this way? Why can't we just use casting? This is because if you
have a player character, and your player character
has an interface enabled, and let's say we have this
function called interact, let's say to pick up objects. So for this ball, when I interact with it, let's say, I just pick it up. But I can also interact
with this gate and make it explode or
interact with the MPC, talk to it, or interact
with some other things. I can have one event call,
which calls interact. And the way that event is functions is not defined
by my player character, but by actors themselves, which we will do right now. We already added this event. Let's see if I did not
forget to do anything, this should just trigger, and we should get a new ball. Yes. We got a new ball. And if we can repeat this
process, infinitely, as every time we do this, we will get a new ball. And we got a new bulb. Let's modify our
bowl spawn rabbit. Let's add a node, make it three. So when this is triggered, we go back and go through
the process again. And every time this is
triggered, let's go sequence. We reset our count here
so it can function again, and we redo it. Let's test it out. Res
play. It blows up. We get three new balls, and we can do the exact
same thing again. You get three more balls, and you can repeat this process as many
times as you want. Now, you may have noticed they spawn directly
on top of each other, and that's fine, but not exactly what I would like to see
every single time. As such, I'm going to
change their you know, I will not only
change their size, but I will also slightly change
their location upon span. So I will add this vector. We'll not touch the Z too much or actually actually,
we might as well. So let's make it
randomized again. Let's get random float in range. Load. In range. Again, let's copy
this three times. We don't want to touch
Z axis too much. We don't want it to go below. As such, we are going to have it go between zero
or actually that's mix drop from the
sky zero and 200. Y axis can be -50 plus 50. And X can be the same. You could increase the numbers
to make more variations, et cetera, but this
should be fine. And let's not forget to put
it in, compile, press, play. We have our begin play. Nothing happens.
We have our ball. Let's do it once. We get three balls. And the spund Now let's
change their sizes randomly. We can do exact same
thing as we did here. But we will instead of using three range nodes,
we are going to use one, and we are going to
make minimum one, and maximum, let's make
it three times the size. We're going to input this
into all three values here. Compile, save, press
play, and test it again. We are going to again do this. And now we have cerebrals, and they are different sizes. And we should still be able to interact with them. We are. And now our gait confined, we get three more balls, and we can repeat
this process to fill our field with balls. As we have not set any limits to it, it
will go infinitely. We could add infinite number of balls or we could limit it by certain amount by
doing the noding again, but there is no real need as we are not going to actually
publish this scheme, as this is meant just for
demonstration purpose. Now, we have our
interfaces being called. Let's do it with lights as well. Go to class settings,
implement interface. Again, we will implement
the exact same interface. We only have one,
compile it, save. You may wonder what
are the other ones. They are default engine provided interfaces that we are not going to go through
in this course. But anyway, so we will want to add this
interaction to here. Specifically, we have
target score here. So let's first of all,
move this around. And we will remove this at our interface and implement it. I wish they would just
pop up in front of you, but this is what it is. We will drag this in, and what's going to
happen is we are going to modify this a bit as we have random
color generation here, and we have target spawned here. We will keep the same logic as we used in the
previous level. If the target is
being spawned for 3 seconds, for 3 seconds, it is set false and
if it is false, we will continue with our
operation for random colors. If it is not, we are
going to keep it at green. Let's try it now. We will press play. And when we put it in, all lights will change
into green for 3 seconds. And when the next
time the randomizer is supposed to kick in, it should all go back
to the random colors. But the issue is, we don't actually have a re trigger for this
random color operation. As such, when it is true, we will go back to the delay node and go through the process
again until it is true, and it begins the loop again. Let's try it again. Let's play. Let's get our
ball into the circle. One, two, three, four, and we get our lights
back. Random colors. Now, it would be boring if
we have this huge arena, and this goal is always
going to sit in one place. So instead what we
are going to do, we are going to add additional
functionality to the goal, and we are going to teleport
it around the level. And each time it teleports
around the level, the lights around will
take a look at it, which will let us essentially instantly recognize where it is. We are going to
essentially combine the interface and targeting, we initially added to lights. With the gate itself. Now, we have this gate, and we would like
to it to spawn on, let's say, four
different locations. We could do like infinite
random locations, et cetera, but it's
not a good idea to have it be completely random. What we are going to
do, we are going to create an array,
and in that array, we will have possible
locations for this gait, and we are going to go
through them one by one, and when there is no longer any elements in the array
rift, we reset this. We could do it in a controlled fashion to be exactly the same
every single time, but we could also
do it randomized. So there's a random
possible variations, and we will get a random choice out of the possible variations. Now let's go back to our goal. First of all, let's do it every time the whole operation
here is finished, we will teleport this actor. So let's custom call
and create a new event. Custom event. Let's call it teleport. And what we're going to do now, we need to set transform form for the actor itself, which is self a new
transform value. And what we are going to do, we can calculate the places where we are going to put
it every single time. And in this case, I believe I somehow managed to now it's because there is a compilation error,
so it cannot throw up. Far down, let's remove this. So I could manually calculate
the space here, space here, space here, and space here and use the blueprint to directly put to
predefined locations. Or what I can do is I can
go to basic shapes and find I believe there is a node called target unless they removed in the
latest version. Yes, we have it
here. Target point. What we can do, we can
use this target point. And I will call we have
this one target point here. There's a mark here. It's quite small, but let's go all the way here on the
other side of the screen, and let's get another
one of these and put it back here and move
it all the way here. We will arrange their
locations afterwards and we will go all the way
and put the last one here. Now we have four target
points. We can set. We can go back to our goal. We can create get location. First of all, let's make sure
we have reference for them. So target. Cast to target point On and we are going to
promote it to variable. Or now, I'm going
to remove this. I'm going to convert
this into array. I will compile it. I
will add four elements. And after I'm done
adding four elements, we are going to get this array, get a stargt point. We're going to add for
each loop For now, we're just going to
use it to test it, and we are going to expose this. And what we will do, we will select target. And we should have this
as target point here. We are going to select
them one by one. Going to target point. One, two, three, and four. Now we have targets
one, two, three, four. We will save, go back and save again just
in case we are going to get actor transform
and put it in here. And this teleport for now, just for testing purposes, we are going to run it
once on event begin play. I believe we have it on top, but we are not using it. As such, we can just test it, compile, save, rest play. So it should disappear
from our location, and it pops up here. The reason it pops up up
in the air, first of all, because our target is not colliding and let's
do it like this. Now let's play again. Perfect. And we need to make sure it is rotated in
the correct fashion. And now we have it. It's still a bit in the air. So let's just drag it down
the target bit to the ground. Let's see if it is
fine now and if it is, we will simply, it looks fine. Now, we are going to take the
Z transform of this target. Let's Copy. And we're going to
apply it to all others. This was around 75 705 such
I just use this directly. Now, we need to make sure our rotations
are correct as well. As such, what we can do, we can get a specific one
first by going through a. In this case, I guess
we can just get a copy. And if we put it like this, this will always get first one in the line which
we already have. So let's do one, which is actually second one, compile, let's play, and
let's see where it spawned. It spawned in that direction. Transform is
obviously incorrect. As such, let's go and click on this second one and rotate
it integrate to the left. So red line is on this side. And let's take a look
at this one as well, and this will most
likely be the same, so we're going to do. So let's try it with
second one, compile, save, and press play. Okay, I made a mistake.
Let's try it again. Let's go back. It looks fine. Now, make sure we have
the same for this one, which is number three. Compile, press play,
and it is working fine. I initially put this
a bit backwards, so it would not trigger, but because we're moving
it around too much, we're just going to
keep it in the middle. Yes. Compile it,
save it press play. Now, let's fix the logic for it. And to not clutter ourselves, let's close this one and go
to BPG and grab at random. Interesting. Random array item. Let's make sure it is
randomized each time. We are going to get a randomized element from
these four points each time. We already have preset them. We already have the
rotations, et cetera. And what we are
going to do next, obviously, first, we
are going to test it. It disappeared
into that location as we added Evans baking play. We need to trigger this by
calling the teleport event, and this is quite easy. We are just going to call teleport event all
the way from here. We're going to call
function Telepot. We are going to save play, and let's see, we have
it in front of us. We put it in. B three
balls and new gate. And next what we are going to do is we are going to
go to our interface and call a new function and call it new interesting. New gait or gold. Compile it, save it. This will automatically
adds this to all actors with
the interface. In this case, we
want them in light, so you can just
click on any light, go to their blueprint. Expand the interface. And instead of target located, we're going to move it and implement event
called New goal. And event New goal will
do multiple things. First of all, we will get
this happening a new goal. And we are going to
target the new gate. But first, let's go to here. And after the teleport is done, we will get all actors with
the interface and list it here and call this
event New goal message. The target is all actors who
have this interface enabled. Now, let's just test it. The moment we put in the ball, all lights should go red. They do. Now, we want the lights
closest to the new gate, focus on it, so we
can instantly shift our focus to the new gate. And the way we do is
let's go to our light. We don't need l
spanner logic anymore. Here, if you remember, we had this functionality where we had distance to player. We're going to copy this or topcates and call it
distance to gate. We'll compile this and
go back to Avent graft. We are going to use this
distance to gate here. The way this is going to work, we need to get a
player character here, initially, but what we need
to do now is get the actor. We could hardcode it, but
as I mentioned first, we don't want to
hard references. So what we are going
to do instead, we are going to go BPG, and in the interface, we are going to add an input, and we are going to call it target sorry, actor reference. Let's get actor object
reference play and call actor ref compile it, save it. And if we take a
look at our BP goal, we now have an actor roof. And in this case, it's
going to be self. As we are getting a new reference we want to
get is the gate itself. We go back to the
blueprint of the light, save or no, go back
to event graph. If you for whatever reason, lose or you have too
many options here, you can just close them and find your event graph here
on the top left. And in the distance to gate, we need an input. So we are going to add input. My apologies. We are
going to need an input, and we are going to
call this input an actor reference,
actor reference. And this new actor
reference will be the gate. And if you go back to graph
here, what we're going to do, obviously we are going to
trigger this to make sure our random colors stop and we get the red color for a second. And as this all happens, we will get this reference event Ni goal, put it into gate. The one triggering this
event is the gate, and the gate will
reference itself, and the interface will transfer that information to our
event here in the lights. So we're going to
have this here. And what else we
are going to do, we are going to add
additional output, and that output will be also gate or we could actually skip this part because we already have the
reference in the blueprint. There is no reason to
over complicate it. What we are going to do is we are getting a
distance to gate. And if the distance to gate
is essentially by branch, true, or this is a distance of if it's
closer than 2000, right? We are going to put this here. So if the distance between itself and the gate
is less than 2000, it will get this value, bullion, and this bullion will define if it
is close or not. And if it is, we are going to get
our set target node, which I believe we had here somewhere in
the player section. Set actor rotation or distanced
player after we set it? Yes. We had this
get actor location. Oh, yes, we did not set there. We set it here, and we will set our new target which by the way, I could have just find a note, but it's always better to
go through your blueprint. We will set our new target. Essentially, if it
is close enough, we will set our new
target to the gate and we will run this event similar fashion to
what we had here. We are going to get
we are going to set our new rotation and
get our own rotation. What we can do easily is we can duplicate
this function as well and make it found gate rotation. And add an input here or actor or actor, call it gate just to make sure we only input
the gait reference here, scroll up at our gait
function, gate rotation. We set our target. We get it as a reference We are going to your move get player character and
set it as a target. You'll get the
targets new rotation. There's no reason to set it
anymore as we can instead get this And in this case, the self here is not being
used as we did not need it. And we can copy the exact logic we have for the timeline in the below here for timeline. And we are going to copy this We're going to copy this place here and
use it from the start. Our outputs will be A and B, and everything else
should remain as it is. For now, let's test it. We do this. We put this in. I explodes. Gates nearby should focus on it,
but they did not. Let's see why this happens. And let's go back to nib print. Now, this gets triggered. This gets triggered as
well. We trigger this. We set target spawn and the reason why this keeps triggering is we are not actually stopping
this from happening. By this, I mean the
random light movement. We need to add this note
here and add it here. And if this is false, as we said it here, this should not trigger, and this only should
trigger if it is true. And by default, it seems to be let's
check it just in case. Okay, it's not
happening currently. We are going to my
superior game skills did not shine through
here. We are getting red. And these actors are looking in a different directions
than what they should. Let's see what's going on here. Our output A is here, which is our current rotation. Oh, we don't need to get
the targets rotation. This is a mistake on my part. Let's try it again. And now we get this interesting
interactive. We have B rotation here. Let's put it down, and
we have a rotation, which should be its
own current rotation. Let's take a look at our event, the way it's played out here. We get our output
values, A and B, put it in and we have Alpha
we have Alpha rotator, and we get setter rotation, the same way we do here. The only difference would be is when we update
it and we finish it, we need to make
sure set this back to true finished. True. And the timeline
for it is 1 second. Let's make it 3 seconds. Compile, save, go
back to Event graph.
24. Gameplay: Let's take a look at
what's wrong with our blueprint. Just
to double check. We have this target
span when it is true, this should stop triggering, as we do not want to topin so it should
not trigger on span. It should rigger on false. And in true, nothing
should happen, and we should be
getting random colors unless it is already spawned
for the next 3 seconds. Here we do exact same
thing. We have a delay. After serial delay,
it falls again, so this all can function
as it previously did. Let's take a look at
our distance to gate. It is as it should be. Let's look at this,
and here is the issue. We need to put it
in here as well. Sample it, save it. Let's see if it works now. We only need lights closest
to the gate to fox on it. Which they did, but
it was quite delayed. This may be mainly because we have too many timelines
running at the same time. And while this playing
from the start is fine, we need to stop these other events or timelines from playing
when we do this, as they need to be
paused or stopped. Now, the way we can
do this is make sure, first of all, we have a
way to interact with them. So let's add a sequence. And in that sequence, let's drag this in. When it is well, essentially, there's a
new target being located, we stop all existing
timelines first. And this should not happen
on event to begin play. No. This should happen on
event, new goal instead. So this should not happen here in folds,
where you are going to do. Why did I remove this? We can just pull it
up here for now. This is very disorganized
at the moment, but let's not waste
too much time on it. Let's take this and put it here. So when new goal is triggered, these two are stopped
instantly and we get our lights to focus
on the lights instead. So let's do this. They show up. And let's see. They start their
random movement. No, as we did not add any
additional information. So first of all, let's
make sure more lights can Fox gate as we want it to be apparent that
something is going on. Next, after all of this has been finalized and we have
finished our play, we need to go back all the way back to sequence zero here. Let's play it, and
let's see it again. We do this. Me let's focus on it. Now, let's change
some settings again. This is a very
disorganized code, which we will organize later. Let's take a look at
what our code does. We get our lights, we get our rotation, et cetera, and do remember this
is per light basis, so it is not like all lights are affected
at the same time. Lights that are not close
enough should not be affected, so we need to change
the placement for this. Node if the target
is spawned and if the distance to gate is
true, this should trigger. And after this stops
the other two, we repurpose this and lights that are close to the new gate should
function instead. Our gate focused instantly. In this case, our
gates respond here. Let's make it sure we
are doing it again. We will repurpose it also again, and what we are going to do
is we are going to make sure only the lights around the gate are red
instead of all of them, as it doesn't serve purpose
for all of them to be red. So instead, what
we're going to do, we are moving when this triggers and when
goal is scored, when goal is scored, all of them turning green
is kind of cool. Cool. It's like cheering on. And we are going to
make sure we have enough time for the lights
to go green when we score. Let's go to blueprints. Let's go to our goal. And before the teleport happens, let's give it delay. Delay and we have 3
seconds of green light. So let's make it 3
seconds as well. Teleport green. So before the teleport
event is called, which we'll call this and
all of this will happen, we will have 3 seconds
of green light. I am really bad at this game. We will modify the speed on
the player a bit later on. And we do this, 3
seconds of green light. It disappears, and
after it disappears, all lights should
focus on it. Yes. Now, let's see what
is the issue here. This event, distance
to gate has an error, and let's see why
this error happened. Our distance to gate event is called all the way over here. But for this to be functional, We don't really have
a lot to go on. So let's take a look at the. Access node Roy red
probably gate gate. Less than 2000, we get auction. So they're trying to read
the node called gate. And by the way, this is now less than 3,000, but it's sin. And instead of less than,
let's just call ss. This is the value
it's trying to read. And if you take a
look at the graph, the target after new
goal is created, it gets a reference
for the new goal, and this reference goes
through distance to gate. And if it is closer
than the certain range, first of all, let's make sure our light change values
actually come after this. So we will save this for now and get this branch node to
be before all of this. We get this distance. If it is less, we go through, and from through, we go to do this, and from here, we go to sequence and this sequence of operations
should be more correct. Let's test it out. We
have this, we drop this. We have this screen, one, two, three, it disappears. If they're close, they should change their color and turn red. But for some reason,
they did not Now, let's fix all the issues we have with this light
and be done with it. The reason why this is not functioning as the way
we want is because there are multiple interactions here just don't follow the
sequence properly. So first of all,
let's make sure we don't just while we do
need event begin play, we don't want to have
these nodes come all the way from all over
the place every single time. So instead, let's
click constant event. That you can just call. Let's call constant event, and we can just call it restart. Essentially restart the whole operation from the
very beginning. This will get triggered every
time the restart is called, and we can put it here, for example, art, call function. And we are going to clean up
our scene quite a lot here. We have this sequence trigger and we have this sequence
trigger from here, go back to our distanced player. Let's make sure this instead of going
to our distanced player, goes to restart. So we will call this
function here again. We can just copy this
and paste this here. So when this whole everything here ends and it is finished, we test our distance
to player and if everything is
as it should be, we restart the whole operation. Let's take a look at here again. We have restart,
we have sequence that differentiates here, we have events that run. And when this all finishes, we restart our node. We stop these two events here. But instead of using this
we can create custom event. Call it stop and we can control my bologies we can wrack this all
the way down here. And instead of having this node, go all the way here, what
we can do is remove this. It is true, this just follows. We use the stop node
to stop this one, and we add a sequence here. We stop this one on top and we stop this
one on the bottom. Much cleaner. Spaghetti code. We don't have anything
we really need to clean up here anymore
on the bottom row, and we can just move
it around a bit. And here, let's take a look. We are stopping it
when we need to. We have this delay that goes all the way back to
random generation. Instead, let's call our
restart function again. So for it to check. There's a delay after
it's all finished and we restart everything again and
the restarting everything. We'll go through all
this process once more. We'll get our new random color. This will trigger. Let's make sure everything here is
inside comment section. We have double branches
for distance to player and distance if the new target is
available or not. This is just a cleaner
way of doing it, so we don't have to
get that nightmare. We could create functions, et cetera to even
more compact it, but I believe it's fine. You can, by the way, alt right
click and left Alt click and right click hold
and move around your mouse to change
your zoom levels. And everything here is fine. Now, we have it organized, but let's change something. We should move this forward. And let's for now, destroy our references
here and unattaches. Let's drag our whole
larp, et cetera, rotation, everything here, to the event graph, New goal event. And let's use our target
variable and set it here. That way we don't have to reference the interface
every single time. We get it once. And every time we need it, we just get it
from the set here, and we do this for here as well. And when we play, when
we are finished playing, we set the target spun
and go to restart. And before we move
around the lights, we want to turn them red. As such, we are going
to move them here. And at the right found, we move it and we
play from the start. And when this is
finished, again, we target spun, delay. And I believe we will need to modify this
again just to make sure. But let's compile.
Select press play. Let's see what happens. We move our ball, everything turns green. We get new balls. Everything is focusing this. But now they're stuck on it. The reason why this happening
is because this value here. Let's see what happens again. We move it around. I am a very bad player, so let's just drop it
directly in front of it. We blast it.
Everything is green, it gets re triggered. And we have them here, but they're not
the correct color. So this is partially because we have a lot
of restart nodes. This happens when it is
finished and it is 3 seconds. This trigger advance
and next trigger happens in BPG, in BPLte. If we take a look at
our event goal here, 3 seconds delay target spawn This is not actually
retriggering anything. But this has a delay instead. So instead of this,
let's remove this. And we remove the branch here. We add this delay, but after this, let's add
our restart node, call. And here, let's make sure we don't get our restart
called when we don't need it. We have our branch
going all the way here. This should never go
to distanced player. T should go to branch initially. And if it is true, this
should not trigger. Or let's recheck our bullion. When it is false,
this should trigger. When it is true, it
should not trigger. And when random radiation
and generation is in place, detector rotation,
we are delaying it. We are getting distance rotation,
we are getting through. And when we get this, let's
remove this from here and add additional restart node here. If it is true, compile. We have the sequence that stops these two timelines and
after they're stopped, they are not being
updated real time. As such, we can just
move it around a bit. We are getting
actual transtation, and when this is finished, it checks if it is close
to the player or not. If it is false, we set
our rotation to default, which we don't
have to do anymore because we modified
our light system, and if it is false, we restart our light system. So let's try it again. Everything is working
as it should. When I'm close to
lights, they aim at me, I put it in, and let's
see how it reacts again. They are reacting to gate and
focusing it as they should. And after it is
finished playing, they should start moving around. And the reason why this is
not happening is because we are not stopping this operation at
any point in time. So we're updating it, and when it is finished,
it's restarting. But we need to set target spawn to false before we finish it. You need to make sure
it's set to falls so the lights affected by the gate can go back to
being operational. We put this ball in,
give the moment. Isappeared. The lights are looking at it, and the lights are
functioning again, but now we have an
issue of colors. Now, let's fix that one as well and we are done with
the light system. When event color is triggered, we get our target spawn, set the lights turn green. Let's reaffirm it. We get this done, one, two, but the lights target player instantly
change color. Now, this is happening due
to very simple reason. We have our restart note repeating this random
color sequence as well. So if we just drag this down
from here and put it here, this should solve all of
our remaining problems. Let's get this done and we get our green light and our
green light is here, we get our random
colors and gate colors. Now, we are not getting
our random colors back. The reason is no event is now re triggering
get random colors, which we can quite easily
do ourselves by making sure when this sequence ends and
this sequence ends here, we call an event that
starts random colors. So let's call custom event. Call it random caller B set. Again, not the
best naming sense, but we are just going
to roll with it. And we are going to call this event here on the very
top where we edit our light. And here when we click
the goal, in this case, we don't really have to because after we trigger this event, we get this event on top, so you can just not
restart it here, and it should work fine. We trigger this, lights
follow us when we are close. Gates spun there, lights
turn red around it, and they move around again. The green light here is
remaining as it should because after this green
light is triggered by itself, if they are not close by, they don't get restarted. So we do need to add this
green light reset here. Now, if we add it directly, this will kind of overwrite it. This is why understanding the sequencing in
blueprint is so important. You may think, Oh,
I did it already, but the sequencing
itself may be an issue. They get random colors
and this one turns green. Just to make sure the
rest of the remain green while the green
one is being focused on. Let's do it delay of 6 seconds. This says 3 seconds and we have three second delay
before this begins. So the lights that are
not closed will turn red. And just to make sure we are being able to definitely
see the green my red. Let's get the spot
and set intensity. We're going to reset it. Again, so usually
we have 40,000. Let's make it 80,000. And we will copy this again. And when we are finished and
we are doing all of this, we will set it back to 40,000. So when we are done
with our operation and for gate event, we get them back to. Let's get it down. We get it in. We get our
color, whereas the gait. The gait has the
luminoity increased, and let's get our atentan
reduce is fine as well. Now, the only thing to
change is the color itself. And let's not make
it bright red, make it darker red,
combine, play, save. And we put this in. We get
our lights, where's our git. It's our gate. Difference,
but this should be enough. We could and I guess
we should change the default lumen intensity
level for this 20, and let's make it
shorter range so we don't get too many lights
cascading all over the place. And now let's try it again. We have these lights, and suddenly we get red lights here. And I guess we could make
red lights remain longer, but again, this is just a
matter of choice at this point, and I don't want to waste
any more time on light. So we're going to stop randomizing everything
on the light here now, and let's just use comments and stuff to
organize the event. So score green light. And this one will be new targets. We're going to
make this one red. And this one green. Let's alter them out, see if we have anything else. We have our target, follow
target or to be specific. Follow clear we have our random light movement and our random color
for the lights. And this is enough. We have our new events, we are our event dispensers
that call these events. And now let's make sure we have enough pools in the scene at the
beginning of the game. So what we can do,
we can add No, we can leave this
one on the field. The error message was because we have
referenced it by default. We don't really need
to at this point, but we can leave it
in. It's no issue. So let's just have it here. I want to spawn multiple balls during the event begin play. So let's just add a lot
more balls into the scene. Just to do have ing the scene. And what I'm going to
do because I added so many bolspwers
and I don't want to actually make
a balanced game. We're doing it for
demonstration purposes as well. After all, what I'm going to do is instead of doing
this event N times, I'm going to add begin
play and on begin play, I will do N, essentially doing this
event three times. And on event goal score, I will reset and do it again. So at the very
beginning of the game, this will spawn a lot
of balls for me to use. And if I score a goal, which is kind of hard for me for some reason, let's try it out. We add this ball and Bam.
We have a lot more balls. What we can also do, we can take all our ball sponers here. Shift click and put
them up in the air. And I believe let's
center it a bit more. And now they will
drop from the sky, and let's add them
into one folder, call it A underscore Spooners. I don't have to use
underscore in folder names, but it's just a force of habit, and we will have
one green ball at a very and our starting
ate is there, so we can just begin by
placing these two here, and we can begin our game lexis. And as we begin our game, we have a lot of balls
to work around with. We can move them. And
as we put one in, we get even more balls, and balls cannot go out of field because we have
collision there. And now we have a game of infinitely generating balls
until you drown in it. Now, we are done with lightning, the gait and gameplay elements, the interactions between them, and we are going to stop gameplay additions
there in this course.
25. Third Person Character: Now, let's talk about third person character and
what we can do with it. In this case, third
person character is our unreal mannequin that's
provided to us by default. I will explain some
of the parameters that you can add into it and some useful components that we can use for our actors, and perhaps we may even put few as decoration
in the label. If you go back to
your content folder, third person blueprints,
you will find your third person
character, open it. And you will notice
there's a lot of things here for jumping, movement, enhanced input actions, which will not be
explained in this course, but they are the unreal new way of adding input into actors. It's a topic for
the next course. And here we have our
viewport, our character, our characters collision
box or capsule component, and our camera that follows the character our character
movement component. So this is what we are
going to focus on today. We have character
movement component here, and if you take a look
at the details panel, you will see a lot of
things you may find useful. So we have our acceleration. We have our movement speed, swimming speed, et cetera. We will not be focusing
on each one of them. What we need is our speed. So we have maxw speed
of 500 at the moment, which I do not find particularly high enough to navigate
this huge area. It feels very slow.
Let's increase it. So let's increase it by, let's say, and make it
1,500 and make it 2000. Let's see play now. Now, our character is
moving much faster, and we can perhaps
even score something. And when we hit something, our movement speed drops a bit, but we can catch our
balls and navigate them. Let's try it again. We can now find our different gait and do it again for yes. And we can repeat this as many as we want and fill the
whole screen visible. Now, you may notice we now have Max lk speed of 20 k as
I put it in previously. But if I control Z and put
it back to 500 or control Y, too, the differences
here is huge. The fact that you can just go at a higher speed higher and higher speed is because we have a certain
amount of acceleration, and unless I hit something, it will drop we are going
to decrease max speed, let's say, let's just
divide it by two. I believe that number was
too high for our purposes. So let's see, and we still
have a high enough speed. But what if you want to have a certain amount of acceleration but don't want to instantly
go to high speed possible. This is where our
acceleration comes in. And if you take a look
at our acceleration, our max acceleration
is currently 1,500. If we put it into a
higher number, let's say, 5,000, compile, press play. We will get instant boost speed, and it will go higher
and higher and higher until we
reach our max speed, which I believe is
already too high. So let's put the acceleration to 3,000 and make sure our max speed is nowhere
near this ridiculous number. We reset it, it is very slow, so let's put it like what
can we do here? By default? It was, I believe, 500. And let's multiply
it by let's say six. And our max acceleration
can be multiplied by two. We have additional
options here for gravity, how much gravity should
apply to this character, we could reduce it,
which would let us jump higher and our drop
will be slower. What we can do, we can
increase our jumping velocity. So let's double our
jumping velocity, and let's say triple it. Compile it, press play, and now we have a Superman jump, and we may actually
jump out of bounds, which is not something
I would like to have. So let's reduce our
jumping by 300 defaulted, and let's do it 800. Step. So let's go back. We have high I
would like to have high enough jump to
jump over the balls, but not high enough so I
can go out of the level. I could always add a walking
ball on top of the level, but we are not going to do that, as we purposely
limited our jump. Instance. We have air
control that lets us adjust how much we can
control the character while it is moving around, and we have a lot more
settings for flying, for swimming, for
physics interactions. And this is what I
want to focus on. We have a game where we are
moving physics based objects. So we are going to hide all of these options we
don't actually need. And we are going to focus
only on our physics. As you can see, there's
a lot of options here that would take
forever to go through. So let's just
search for physics. And we have our physics
interactions options. We have enabled
physical interaction, which is true, we need it. And what we have for Alvin
bounds into a physics object. So when we hit an object or collide
with it to be specific, we apply a force of 500 to it. If we increase it to something like 5,000 compile and play, and we interact with an object, let's say, it's getting much more force
applied than before. And if we add a
ridiculous amount here, let's say, it will happen, they will just instantly evaporate the moment
we touch them, which may look funny, but it's not ideal when everything you touch explodes and goes into
oblivion in a second. But I do want some extra impact when we touch the spheres. As such, we are going to
press play, and let's see. Our force is now enough to drag down multiple balls at the same time and we
can just move around. And with our increased speed, we can repeat this as
many therms we want. Now, here we could also click on this and if we increase
minimum touch force, essentially the
minimum amount of force we can apply to
something like let's say 2000 and let's say
it's also our max now. If you compile and press play, we will get this
weird interaction. We are not actually
doing much different. You may wonder what
is this in this case. Is this the amount
of force applied, not the push force. As such, it's not
exactly the same thing. It is a calculation based
on amount of force. If you are trying to add
additional force per kilogram, which is useful for
physics simulation, but it's not something that
will help when it comes to pushing actual objects. Let's make sure we still have our options enabled
as we wanted, and we will now
exit this section. And we are going to talk
very briefly about objects, components, actor
components to be clear. So we created few
blueprints already. And let's create one more. And this one we are just
going to make a actor, we're going to call test for now because we're
not going to keep it. We are going to add a mesh, and let's say we add
a static mesh here, and we can make this static mesh into let's do this pyramid. Let's also add the
material for it because why not?
We compile this. And if you click
Add here on top, you will find a lot of
components you can add. We have AI elements, we have audio cues, we have additional shapes, camera, spring arm, et cetera. All of them are very useful and they're topping of their own. But what we are going to talk
about here are movement. We have floating, interment, projectile movement,
and rotating movement. Projectile movement when
applied to an actor, let's go and put it
back to the level. If you're a projectile
movement, here. Applied. Then we go
to project speed, and let's say project
speed is 10,000. Let's make it a
smaller number so we can we don't have
trouble seeing it, and max speed is like 2000, same point as before, acceleration and max speed. And what we can do is we can disable gravity on
this if we want to so that it doesn't never has gravitational
pull or anything, but we are going to leave it
as it is and press simulate. These events are
going to give us a lot of errors as there
is no player character, but you may have noticed, instead of staying in one place, it pushed itself forward. The reason why this saving is because of projectile movement. This is regarded
as a projectile. And if we reduce the gravity scale to zero,
compile, press play. This will just move
forward to infinity as it doesn't have any project
gravity applied to it, unless this actually hits
something and destroys itself as a projectile
which you would need to add in the blueprint
section of the projectile, this will just go infinitely
in one direction. This is quite useful for
making games, obviously. Where you want to
have projectiles, bullets, perhaps some kind
of sphere or objects, if you are making two D, not two D like A games, where you want to have some interactable
actors that you can spawn and destroy and they need to move
in a certain direction. You can use just
projectile movement. Now, let's take a look at
the other movement option. This one is rotating movement, and what rotating
movement does is, which is it rotates in a certain rate at a
certain direction. So if we go back to the level
and let's make it bigger, let's make it much bigger. And let's press play. You'll notice it is moving
around in its space. You can use this as a
decoration in the environment. If you want some
objects to just rotate, or you can use it as
a gameplay element. It's up to you. But all this does is just rotate the
actor in one place. It is most commonly used
for pickups, such as coins, heltrops, met kits, and stuff in the games where you have this pickup just
rotating in one place. This can be used for
purpose of not you don't have to add
additional elements to your blueprint other than just rotating movement
to rotate them around. And that's a time saver
for a very simple thing, which usually takes a lot more because you need
to call an event that rotates an object in a certain radius
in a direction, every frame of the game. You can just skip all
that and just add this. So if you need something to just rotate in one place,
use rotating movement. Instead, you don't have to
use complicated vector math. And that's pretty much all we need to remember
that Unreal is a very, very expensive tool
for game development. It has everything. Like, it has so many things we have not even talked about, even mentioned. I tried to cover as
much as I could, and I'll keep it to
minimum, complexity. But you all need to start
somewhere to learn this engine. And to move forward, you need to first of all, learn these very basic skill sets. And what's more important that you need to
understand how actors, how code, how everything in the CD world interacts
with each other. So you can engineer your way to what you are
trying to actually create. Don't start with
overly complex ideas. Even the simplest
things in games are usually a complicated
process to integrate, and some very complicated
things may actually be simple. It's counterintuitive
in most cases. The hardest thing in this prototype we made was actually the
light interactions, the fact that we had
to do them so many times in so many variations is just a testament how difficult the light systems in all
game are in general. Usually, you wouldn't
even want to have this many lights as it
is performance savvy. And in this level, the simplest thing to make was actually the gameplay
element itself, which was just shoving the balls into the gateway and
making them explode. The moment you add any amount of complexity to your level, as having multiple lights interact with some
other actor, et cetera, the game suddenly becomes an
engineering task where you are trying to make sure
you don't use a lot of resources, but
at the same time, you are trying to make
something that will look good, will be fun, and for all intents and purposes,
your dream game. There's a lot more to cover. As such, we will be releasing intermediate and expert
level courses in the future. And we will also have individual courses for
some subjects that require their individual courses to go through them,
such as material, lightning by itself, animation, which we did not even talk
about in this course, how to create animations, how to apply animations, how to do AI inside unreal. And by AI, I mean not only AI for movement of the
characters in the game, but also AI itself, like AI generative note
based programming. You can do a lot of
things in unreal, other than games, you
can do film production. You can do simulations for scientific
reasons if you want. And Unreal keeps adding more and more functions
to the engine. So there's always new
topics to explore. And there's a myriad
opportunities for yourself to improve. Do keep in mind, you don't have to know
everything in unreal. You need to understand unreal to a degree where you
can work with it. But unless you're an
indie game developer or you are trying to be
in the game developer, you don't have to know
every aspect of the engine. What I would
recommend for you to start learning the basics. And after you are confident in your basics, start
experimenting around. Try to create something interesting, search
for information. If you don't understand
something or if you need a proper
guideline for it, we always are happy to answer your questions and feel free to check out our
other new courses. There will be always
more to learn. And at one point, you may need to decide
whether you are going to specialize
in a certain field in the engine and work as a team with other people
to develop your game, or you are going to scope down your game and work on it alone. We did not touch upon using marketplace assets
in this course, as I want to use as little outside
interference as possible. Because when you are learning, it is important to learn the basics before
you can jump on and download complicated
master material that you will not even
understand even if you see it. Again, feel free to experiment. There's nothing wrong with that, but make sure your
basics are solid. My name is Al Jun
Ab lazade and I am happy that you have
finished my course, and I am happy to help
new game developers and perhaps just casual
unreal engine users improve their skill set. And if you have any questions, feel free to ask them
in the comment section, and I would be more
than happy to see your own creations and no
reason to be shy about it. Anything you share is
better than nothing. Thank you for your time, and I hope I will see you
all in my new lectures. Few additional topics for anyone who are interested
in game development. When you are starting the
game development process, it may seem very
complicated and it may seem very scary and
it is complicated, but you don't have
to be scared of it. The game development process is a very complex interaction of different fields such as mass, creativity, artistic
representation of your own taste. Coding skills combined
with animation, modeling, production qualities
like planning, story writing, there's a lot
of things in a single game, and quite honestly, the game
may be as complex and as difficult as you want it to be or as simple as
you want it to be. You don't have to
make a difficult game to learn how to make a game. It's better to start
with something small. And the biggest
reason why a lot of game developers are
having a lot of issues is poor planning, scoping too wide, and trying
to do too much at once. And in the process
of this project, as they are
developing this game, they lose motivation, they
waste time, they lose money. And all of this is
part of the journey. They are trying to complete to get into the final goal
of being a game developer, perhaps releasing a very successful game
and getting rich, or you may be just trying
to make a game yourself or you would like to play or some other people you would
like to show your game to. Regardless of your reasoning on what you are trying to make, when you begin learning
any game engine, not limited to unreal
engine specifically, but still applies, start small. Pick a simple idea, pick a simple game, that you can finish in
ideally few months, at most half a year, finish it. It doesn't have to be good. It doesn't have to be perfect. You can have as many bugs
and mistakes as you want. Just make sure the game
has a start, a middle, and a finish, and everything is more or less
working as it should. And that alone is
a big achievement where most of the
game developers fail. Releasing a game even a bad one is an achievement when
you are doing it alone. It's a different topic if
you're part of the company and you are as a big company
with hundreds of workers, you are trying to make a game.
That's a different topic. But when you are learning and where you are in
the game developer, starting just don't
straightaway jump to MMORPGs or multiplayer games or overly
complicated mechanics for your game.
Just start simple. Make a horror game, make a Mio make a platformer, which can be complicated, but just keep it simple. The game development process may be one of the hardest
fields in general, because it requires
a lot of disciplines that don't usually
interact with each other. You may need very jazzy music for the game you have in mind. But you may not have the
skills to produce that music. So you will have to
either learn how to make that music in addition on how
to make the game yourself, or you may need to buy assets which are not always exactly
what you want to be, which is the most
reasonable option. In most cases, find
someone who can make that music and is willing to
help you in your project. You don't have to do it alone. You can always get some
people to help you. It may cost you money unless they're your friends or family. And you need to
remember that while the games themselves are fun to play and easy to
look at and be like, Oh, you know, next big game, I will make better copy of already existing game and make it much
better than that one. I will take the same
ideas, same principles, make them a bit more different, be more complex,
and make it bigger. Someone already before me, how hard can it be? That's a nice pitfall
to jump into. You assume it's easy
to do, but in reality, there's a lot of work put in the background of a lot of
games that just seems simple. You may take a look at simplest games are usually shooter games from the
implementation and horror games. You have a guy who
shoots other people, and you may be thinking, Okay, all I need is a guy
who moves around, a gun, a bullet. And other people to hit for the And you may be assuming this is all you
need. In a sense, it is. But when you start to
implement this into your game as you are trying
to polish your game, you will notice a lot of
things don't feel right. You should have gone, but it doesn't feel
as impressive. You look at the environment, it's something is
missing from it. This is because a
lot of details in a lot of games are not really apparent at
the first glance. For example, in the previous shorter example I
just mentioned, the gun may have an impact
frame when you shoot it. It may be the sound.
It may be the VFX. It may be the camera shake you
get when you fire the gun. The environment may
need more wind, maybe some additional
fanges or variation in it. AI may seem like stupid as they are just baking at you and shooting while
standing in place, while a professional
made game may have an AI that is trying
to actively take cover and shoot at you from a better position or run away from you when they
are low on HP or high. Sadly, there's a lot of
games that ignore a lot of aspects of the game
just by trying to copy on already existing games. But you don't have to copy the already existing game
genres or even game elements. Feel free to experiment
and do whatever you want. There is nothing stopping
you from making a game of thrones kind of game and
they're all actors being candy, or stones or rocks or doughnuts
for all like, we care. And you can just take this weird concept
and make into a game. You can make it into a shooter, you can make a tactical
RPG, et cetera. You're while it this idea I just mentioned may be
complex to implement, there is no real
reason why you can't, other than the
amount of effort and time you're going
to put into it. You have full creative freedom to create whatever you want. Don't get stuck on just copying a template or
someone else's work. Just get creative.
Get passionate about what you are
trying to make. Don't try to copy
someone else's work. This is not a school. This is not an exam. You don't need to
pass a certain grade, and you have no way of doing it just by copying someone
else's work directly. You may try to improve
someone else's work by getting an inspiration from their work and improving it to the point where now it's no longer their
work, it's your work. And the next person who
is going to play a game will look at your work and
be like, This is impressive. I will copy it and they will
copy your game elements. And they will most
likely fail because nothing bits original
in most cases. To keep it simple and
short, get creative. Don't be afraid to experiment. No real reason to copy
paste other people's work. And don't over scope in your projects and just start
something and finish it. And the very first
game you finish making will feel very different, and it will most
likely not be good. It may not sell. It may get bad reviews. Don't take it to heart. Take it with a professional
attitude, improve. The critics ems and use it as a fuel to further
improve your game. Don't give up in the
middle of the way. This is a very long journey
you're stepping into. But I believe it's worth journeying this path and we can journey it together. Thank you for your time. I hope I see you in the next lecture, and I hope even if it's
not in the lecture, I will see your
work down the line. As such, feel free to share your projects
if you are working on any or just a samples in
the social platforms. And if you have any questions,
feel free to reach out. I'm more than happy to help. As a fellow developer, it would be my honor to help you all out in
making something cool. See here and have fun.
26. Widget BP: Hello, and welcome
back to the lecture. In this lecture, we're going to add UI elements to our games. So in this game, currently, we have our balls, we have our goalposts, but we don't really
have any points or HP or any other UI
elements in the screen, and we are going to add them
with Unreal's widget system. So to do this first, let's go and create a folder. Let's go to blueprint
call folder and create an info folder
and call it widgets. Or just a widget should be fine. Here, we right click and
here we go to interface. User interface and click
on Widget Blueprint. I will just call it
UI Widget underscore, UI. That's all. You will get this Widget menu, which is your designer
menu for the widget. You also have a graph,
which is very similar to blueprint with
slight differences. So to understand
how widget works, first, we need to create our
UI elements in the widget. And after that
widget is created, we will attach it
to our viewpoint. So our screen in a
certain position. Now, let's decide
first what we are going to have a widget. For example, let's
add a score of how many Let's see points we score. We get one point
for each sphere, we get into the gate. We can make a
widget to calculate our speed to show us at what
speed we are running around. And quite honestly, we
could do a lot more stuff. Maybe we can put in the
time allay elapsed as well, and we may actually add end
game to this mini game. Now, first of all, let's add this stuff here. Now, now that we have
this widget interface, let's take a look at
elements on the left side. You may notice we have elements that may be useful for our UI. So we have sliders, we have images,
buttons, et cetera. Like imagine this being a
button that you would use. So let's say it can have a
text on it called Start. And when you click this, something happens, et cetera. For now, I'm going
to delete this You could just put in the
element you want and place it where you want in the screen and code
in the logic for it. But the better use of the UI elements is when they are in a certain
panel or canvas, if they're going
to have something like a list of an inventory or you want the widget to be movable from one part
of the screen to another one. For example, imagine some chat boxes in
multiplayer games. And click on the
chat box and move it around for that
to be possible, it needs to have a widget panel that you can just move around. And obviously, you
would need to code in how it should
be moved around, but we are not going to go
that deep in the widget. The most general use widget we have is called Canvas panel. And Canvas panel here is
quite performance heavy. It's just probably not the best way to do it if you're trying to
optimize your UIs. If you have a lot of UI elements in your game and all of them
are using Canvas panels, and you're constantly
updating them all, it will add a surprising
amount of cost your CPU usage. And may even start
lagging your PC, et cetera, and you
may wonder why your game is lagging when you have optimized
everything else. It's most likely
because you messed up here by putting too many
UIs with canvas panels. Again, the performance
cost is not very high, but still it may get very high depending on
how complex you make it. So for now, we're just
going to use Canvas panel. And as you can see, we have this Canvas panel, but we don't have anything inside. For now, I'm going to resize it. Let's go back to our level. So let's imagine what
we are going to need. We have our character here, and we have our character,
and by the way, if you press F eight, you will get your mouse back while this character is still
in the middle of s game. And if you click, you
can move stuff around. So it's simulate it's kind of a mix between
simulate and just play. You just press F eight after
you start the simulation. So you can test stuff. And this way, the references to the player character will not break because it still exists. It's just we're not
controlling it at the moment. So now we have our character, and we had a very we have
this camera view, right? And I'm just going
to press Fight. Just so you can see my mouse. Let's say we want a text on top right that says how
many scores we got, and let's say on the
bottom right here, we want to have a value that shows how fast
we are moving around. On the center of the
top of the screen, you could also at a time elapsed, just for
the sake of it. So I can show you how to make
second time based widgets. Now, this should we now have
an idea for what we need. So let's create our widget. First, let's add a text block here as a placeholder for now. And let's see. All we will need is
really text boxes, but I'm just going
to add an image as well just so I can
showcase how to use it. We could make a
progress bar as well. Yes, let's do a mix of them all, even though it's unnecessary
for this mini game we have, just so I can showcase. And let's call this text block. On the top right, we are going
to have our score, right? So let's have score. This is just a
placeholder for now. And let's say we
have a progress bar and instead of
let's put it here. Let's say if we reach
as we get in score, we will get a progress bar. And let's say when
reach the score of ten, this progress bar will
fill up and we will essentially win the game or
do the mission or whatever. And this image can just be
a UI element we can use, and let's put it here. We are just going to have
it in a certain color or with a certain image
with some numbers on it. So we will need a text. And if I drag and
drop it on here, you will notice it did
not get attached to the image because while
Canvases can have children, this image itself
cannot have children. So I would need to perfectly
place it on top, ideally. Or I would need to
but you may not, depending on the
size of the screen, this may get up to position. So if I put a text just
here as a placeholder, just going to change. 1 second. Oh, yeah, let's change the color of the text
so you can see it. If I move my screen, the text may get out of
position quite easily, especially if I don't put
proper panel in a proper panel. So what I can do, I can
create a box or an overlay. So I can add overlay here. And inside this overlay, I can add this image, and I can add this text box. Now, this overlay is acting as a border for our
textbook and our image, and let's make our image bigger. We're going to get it into
center. And let's see. You may notice something
interesting here. I'm not able to
directly resize it easily because it is so small. So let's instead what we can do, we can click here at
this button, fill. If you just center
it, this image, empty image we've added has
no real image inside it, so there is no reference
for it to get. So what you can do, you can just backdrop this and enlarge it. This text block can
be in the middle. We could enlarge it, but it doesn't really do
much for the text, and we put it directly center
to center by aligning it. We could edit the padding, et cetera, to make it. For example, if we have this like this and we add
a padding of 50, it will move 500 would
be something like this, but there is no
reason to do this. If you just want to center it, you can just center
it by doing this. And now, this will always remain in the center of
this overlay widget, and you can just put this
overlay widget where we want. And this overlay
widget we are going to use can be selected and put exactly where
we want it to be. Now, I like my positions
being solid values, let's just put it like this. Now, our text block will always be here
regardless of the size, et cetera, the screen or the device you're playing
with, and which is fine. Canvas panel itself,
as you may see, is we put this widgets
in outside it, and I made a mistake of
clicking on I should click on the overlay
instead of just image, and let's move them in. You can check your screen
size specifically if you want here if you are trying to
match a specific screen size, or you can just click the fit custom and
put in, for example, let's say, 180,
54 as 180, right? So this is a screen
size I'm aiming for. Obviously, I can just
click Fit screen, which would be my screen. And here on the bottom, we're shown our DPI scale, which you can
configure if you want. But it's not necessary, so we're going to skip that part and focus on
what we are doing here. So, let's go back to
what we are doing. We have our score. We
have our progress bar. We can add time
after this as well, let's do my apologies. Why am I dragging it from
here? I need it from here. Okay, so let's at
time elapsed here or maybe to keep it
clean, let's add it. No, no, no, let's just make it in the middle of the screen. Now, we have This is
going to be our time, so I'm just going to
change the name for now, so I remember why
I put it there. This is not going to be You
could put in the content for your containers here from here and you can modify
them, their position. Their color, their shadow, if they need any image, there's a lot of stuff
here you can check out. You can change the phons. You would need to download phones if you want
your custom phones. You could use
typeface, et cetera, like Italic letter sizes, everything you want to
change, you can do it here. And always, you can just call
it click on sized content. In this case, the size of the widget will
match the content, which is important if you have a widget that has a mechanic like click on the element in the widget element
of the widget. Let's say you have an icon. And if you want to
click on the icon and you want to, let's say, drag it around in the inventory or just activate it or whatever, you may want to just size
to content, the widget. That way, the widget is exact
same size as what you see. Obviously you could
fake it by making a transparent image in the
background gave it bigger, but that's just why would
you do that nonsense, right? So just keep in mind, this is a good way of
making sure the size of your UI matches what
the content is. So this time, if I add extra
letters and per center, now my widget is bigger. Meaning I can just press on
the X part of this widget, and it will still
trigger the event that we will create for it
to be function or whatever. Now, let's go back. Now, we have our widget, which is not really
functional at the moment. So let's do this. First of all, let's make sure we do something with
this image tag here. We have this widget, which is just a brush
of white color. We don't have an
image set up for it. So let's just select a random
image or texture we have. I do not have any
widgets uploaded, but quite honestly, I could
do it with any texture. So let's see. Let's just
use unreal widget for now. Just using re logo may
not be the best choice. Let's do this, yes. And we can move this with here. Now that I think
about it, it may be a bad idea to use this logo because it is making
hard to see the texture. Let's find you could
also use materials, but this will not be functional. You would need to
create a UI material, which we will talk about later. So let's just for now,
just pick this color. Just pick a random texture. And yeah, let's do this. Weird texture. I'm not even sure what it's for. We are going to use this. And we have this progress bar here. The way progress bar functions is similar to how you expect, but you need to put in the
values that it needs to, you know, fill in the progress. First of all, we have
its default color, and we have fill color. And what you need
to do to make it. Okay, let's for now remove this. Keep an eye on
this progress bar. We have the progress of 0%. If I increase this, you will see it's increasing
in the screen here. But you may notice
while it says percent, it is the value of zero, one, zero being zero,
one being 100%. So you cannot just
input a value of 50%. You would need to
convert your value to a percentage and convert that percentage
to a value 010-1, and put the value here that way. I will show you how
to bind values later. We have our options, how we want our
progress to feel. So let's say fill from the center will be
something like this. Full from horizontal. This may be a good system for not only persons
for progress, but also how much noise
you're making if you want to This is from vertical
from bottom stop. Obviously, you can change the
shape of this progress bar, so you could just
make something like this or bottom stop, obviously. We're going to keep it
from left to right, and let's make it the
way it was before. There's additional
stuff you can do, but we are not going to
bother too with them. We could add border. So how much of the progress
bar can be filled, et cetera. We are going to not
worry about them. I don't like the
blue color for this. Let's make it red. For now, perhaps I
should make it green, but let's keep it like this. And here we have our
score and our time, and we have our
textblock for speed. So we will need to create some additional
functionality for all of them to
update in game. The widgets can be
used as menu elements, can be as UI elements. Their purpose is to let you trigger something
some code you have precoded or just to keep I updated and available to you as an information
source, right? Imagine a simple game like
how much HP you have, how many lives you have left, like your inventory
items, start, pause menu, settings menu,
everything that is interactable or just giving you information as a UI element. Is a widget in unreal. So we have this, but we don't have any logic
associated with them. The reason why is because
we did not create them. We will need to create
our UI elements. Sorry, UI logic. First of all, let's remove this eventi. And we have here event pre
construct and event construct. It's similar to
event begin play, but the difference is UIs needs to be constructed
to function. So you may ask when
I is constructed, does it not automatically
happen when I begin the game? No. Then answer to that is no. Is needs to be spawned and
attached to the screen, essentially, to our
viewport via blueprint. And the most common way of doing it is to do it in
the player character. So if we go to our
content and go to our third person blueprint,
this is our character. Just to make sure I am looking
at the correct bleprint, I'm just going to scale it up, press play. Yes, I'm gigantic. Maybe this is the proper size. So we are looking at
the correct blueprint. Here, we would need to
add an event to create our UI widget and attach it to our viewpoard which we
will do in the next video.
27. Widget Editor: Now, let's create our widget. Let's create it here. First, we find a node called
create widget and add to. We attach it together. And here we select the
Widgit we created. So we called it we underscore UI, not
the best name for it, but we will want to add
this to event begin play. So let's cut it. I
got event begin play, and we have some
stuff happening here, which is completely fine. We can just add it as just to make sure
we don't mess it up. We can add a sequencer node. We can put it here, this, and here we can add our
create UI widget logic. So the game begins the game adds default inputs
to our player character, which is just keep in mind, this is created by Unreal, and the mapping context and enhanced input system are going to be part of the intermediate
course in the future. As there's a lot of details, I don't want to overcomplicate
this course too much. Just know that this
here is responsible for making sure your inputs are registered when you
are playing the game. So jumping, moving around,
et cetera, everything. They take their enhanced
inputs local subsystem and add the mapping context to it so you can work with it. So what we do here, the game begins player
is created apologies. And first sequence
does input and the second sequence
does the viewport. And this happens instantly, pretty much, so you
will notice difference. So for now, let's compile, save and press play. Our UI is actually
on the screen. But you may notice it's kind
of in a weird position. And this is because
we need to adjust our UI designer so first of all, let's make sure we
anchor our elements. So what anchoring does, anchoring makes
sure your elements stay in a certain
part of the screen, and you can do this by clicking here and clicking top right. Or you can just click
here and click here. So this score now is always
anchored to this point. I could move it around,
but there's no point. So this score is now always
anchored to this point. Let's just do it with our and I want it to
be uniform size. I will just size it content, make it easier to manage. So sizes here no longer
matter as it's sized content, and let's just make
it around 100 on Z, sorry, X, and let's say 100 I don't want it all
the way up in the screen. This has the same issue. We need to anchor it
to a certain point. So click Anchor, click
on the top right, and now it's anchored
to the top right. You may wonder what's
the difference between anchoring something
and not anchoring it. The difference is if the
screen size is different, emergency is a mobile screen. Where should this widget be placed in relation
to your screen size? So if your screen corner
is this right line here, a mobile screen would have
a different let's just go. Let's say, mobile iPhone size, in many of not the moment I changed it to
mobile screen size, this UI widget I have
dropped out of the viewport. So if I were playing this on a mobile to be specific
I pull iPhone five S, this widget would not be seen because I did
not anchor it anyway. But this widget here
moved together with the screen because it's anchored the top right of the screen. That's the point of anchoring. You anchor your widgets to a specific part
of your screen. So when your screen is
in different sizes, of cours different devices, it always remains in a relative position to
that part of the screen. So if you want something
to always be on the top right, anchor
it to the top right. If you want something always
to be in the center of the screen, anchor
it to the center. You have options here. So just do it. Now,
let's take this, for example, and what
we are going to do, first of all, let's I don't
like the screen size, obviously, so let's
just restore. And what we are going to do
is you may notice I cannot really anchor this text or this image because they're
inside overlay panel. So this overlay panel is the
one needs to be anchored, not the widgets inside. So I will do it bottom right. And obviously, when
I move my overlay, it also moves my widget. Let's do it -100 and minus 150. Actually, I guess
200 will be better. Now, also let's move
this to the same place, so we could just do
it 100. Maybe not. By the size content,
it will be very small because it doesn't
have its real size. Let's do it for 100 and zero. No 100. And as for Y, let's make it 200. Actually, let's do 400. And time, we want it to be
anchored to the center, top, or you could
do it like this. But I want it the
middle of the top, not the whole top. So I'm going to do it like this. So also, this gives
a good indication of where the center
of the level is, so I can just put it here. I could position at zero, zero, but that will be on the top
anchor, which not ideal. So we're going to move it
like this, make it 100. We are going to
size the content, and we're going to put
it -50 -25 better. Okay, now they're
properly placed. Now we compile, save, press play, and our
widgets are in place. But you may notice the
widgets are not doing anything right now
because we did not add any logic to them yet. We did everything we need here
in the widget UI segment, so we are going to save
it for now and exit. First, we need to understand
how this is going to work. These two are essentially
trying to get a similar value and
similar information. This is a progress
bar out of total. So what do you like, let's say you need ten points. So this will be a
percentage value of your current score
and a value of ten. So let's say you have
four score, four points. This should be at 40%. So these two require same value
to do their calculations. This one requires speed. So our current velocity, which we will get in a second. And this one is just time
elapsed since game began. So this is a Delta timing. This is velocity, and
these two are just looking for a value they can
use to show your scores. Now, the way we did
our scoring was by kicking a ball
into this gate. What we can do is something
quite simple, really. We could cast to this UI. This UI is always available in the level because it is part of
your main UI, right? There are other ways of
doing it to be very clear. You could do it within
the widget itself, you could add the logic here. But the most common way of scoring points and
calculating is by doing casting to the UI
or doing it from the player, as we already have a reference to this inside the
player character, which is what we
are going to when we are going to add our interface to our
player character. So let's add an interface. And I believe we called
it Tutorial BP interface. Oh, no, no, no. My apologies. I forgot the name of the
interface we're using, so let's make sure I
select the correct one. There's a lot of
unreal interfaces. Let's check. If you
forgot like me, what was the name
of the blueprint? Like just got the blueprint and checks the name
of the interface. Okay, so BPI goal score. Okay. Let's go here
and add our interface. BPI goal score, compile, save, and we have
our goal score here. So what we are going to
do is when goal score happens, event called score. We're going to get this
reference from widget here. So for that to do, let's just make sure we have
this value always at hand. We call it widget. Underscore UI. And we'll put it
here. And obviously, we set it as well. So this is probably
done in reverse. Let's set it and
after we set it, get this value and
put it this way. Obviously, if you're not
sure about your code, it's best idea to test it. Let's go back. So we now have a widget reference
we can use, right? So event call score. When this happens, we want the score to change
in the UI widget. So what we are going to do,
we are going to go back to our UI and go to our
graph editing mode. Let's delete these two. For now, we don't have any events
planned for GameStar. And here, we are going
to create a variable, and we're going
to call it score. And we're going to make it into float value or integer value depending
on what we need, but we are going to make
float in this case. Just keep it simple.
And what's going to happen when this event happens event called
score happens, we will get our value, the score value and plus one it. So we are going to get this score and set it into plus one. We also need to
obviously get it score. So you could just do this. I do not believe there, there is a plus directly. Oh, no, we? Since we are going to just do plus
one, you can do this. So what this does instead, this is by the way, it took me a lot of
time to come across it. I don't know why that made
my life so much easier. So if you just plus one and
put set this here, right? This on top, taking this value, adding a plus one to the
existing value and setting it can also be
done by this node. If all you are doing is adding a plus one to a float value, just keep track of something or whatever, you
can just use this. This adds one to
the score value we already have in the widget and
sets it to whatever it is. So if it is one, it becomes two, if it's two, it becomes
three, et cetera. So we are going to skip
this part and instead, we are going to set this
value directly plus one. And obviously, we
will need to test it after we have
our functionality. Now, going back to our designer, I'm going to show how to bind
values to the not values, my apologies, variables
to the logic you created.
28. Score System: Welcome back. Continuing
on where we left over. Let's just for now, take the score text here. And bind this text
to our float value. So the way binding works is
you bind this text here, meaning instead of manually inputting this
text here as such, what we do instead, we are just going to replace it with a variable or
some other result. So the moment I click Bind, we get a function
here called get text. And you may notice there is no thing in the
event graph here, but we have this function. This function is meant
to only work for this specific with
specific score text here. And it's called Get
text by default. It is going to get confusing if we have multiple get texts, so we are going to
replace the name with something like Underscore score. Well, I don't need
underscore here. But we are going to get score, and we need a return value
in the form of the text. We have our score here, and what we're going to do is we
are going to get our score. And this score value is automatically converted to
a text and put into UI. So our default score value
is zero, and let's begin. We now have a zero on
top of our screen. So let's make sure I can somehow get a ball
into the gate. And it changed to one. Our gait moved around, and it now is two. And now we can do it again and this time,
it's going to be three. So this top UI now
actually shows our score, but it is just a number. You may want, I'm just
going to add another widget that adds a text that
says, Oh, score. So it's like score two dots and number that comes after it. That's a common mistake. Like people who don't know certain nodes in
the widgets make. What you need to do
instead is append. My apologies. That's this one. Yeah. So we need to append, but we need to make sure this
is the correct function. So here is the text. What we need to
append is a string. So append string. And we put this A to B. Sorry, we put this value into B, and we put this into
our return value here. And here to A, we write
down score and that's it. What this does, this change the text value
into string value, puts it into B, and from here, we put this value and combine it with a text
score the string here, we typed in, and it gives output back as a text after it
convert it from the string. I will explain the reason why we are doing this after we test it. So now we have scare
underscore zero. And if we just then
we get score one. We can do it as many
times as we want, and it will always
work as it should. Now, you may notice
we got a text. We took that text,
converted it to string, converted it back to text. The reason why we
did this is unless you change this to text
first, this will happen. If you change it to string, to string, and we directly
input it here like this. Compile, press play. You will notice we have
now zero dot zero. The float value by default, has a additional zero
dot zero after it, which gets removed when we do
it via conversion to text. As I did not need
dot zero value, I just used Lexis. We could also, of course, try to do this with
integer values. For example, if
you want to make, let's say, an integer
value variable, let's we have a score
variable, right? So if we take this and
let's instead duplicate this remove newer and make an integer value and
put in the integer value. And for testing purposes, I'm going to make the
default value on this. Once again, get pre default. That's fine. We change this value to let's
say one, compile. And if I were to get
a string out of it, like Cp, press play,
I will get one. Which maybe what we should
use here in all honesty, but I want you to
remember the difference. The float values have their like there are
additional numbers you can have after zero, like zero dot something. Integer values are
whole numbers. You cannot just have
them like zero dot five. Or one dot five or two
dot two or whatever. So in this case, since we are using a
score based system, we can just use an integer
value instead of float, and we can skip this spot. But if your game requires a value that needs to have
be able to divide it, multiply it, et cetera. So if you are going
to do some kind of mass operations on
it, for example, you need a value of zero dot two or five dot seven
or something like that, you cannot use
integer as a whole. You would need to use float. And if you use float, you need to make sure
you do it this way, or you can always check
these values, right? So I will again, show a way to use float if you want to if you
need to use float, but you don't want to harshly
show the integer values. What you can do is you can do this by which we reduce
the fractal digits. We press play, and now we
don't see our fractal digits, but it is still a float value. So we are still using a float, but we no longer have one
dot zero or 20 or whatever. And you can use this
same value to do other operations and apply
the same value somewhere else without messing up your UI's visual
aesthetics where you don't want zero dot zero, et cetera, fractals to be seen. So we are going to remove this integer because
we no longer need it. I will keep it as float. There's no real reason not and we obviously
converted it to float, et cetera, but still we could
directly put it in as well, and it would still be okay. So there is no dot
one, not dot anything. And we can just use it as it is, and put in one. And obviously, we want
this to be like this. And let's just keep
organized a bit. It's a simple line. Let's play, test it out. Everything is okay. Our function works. Oh, I messed up. Just for testing purposes, I probably should have
made gates bigger. Okay, yeah, it
works. Now, this is our widget logic
for this widget, we no longer see here, this one, the score. You may notice it is
very small right now because I made sure
it is sized content, which I like doing
unless I don't have to, but still it doesn't
really matter in our case, so I'm just going
to keep it lexis. Easier for me. Next, we want to
manage this one. Progress, progress bar. I'm not sure why I
moved it around. And this progress bar, we will use the same value. By value, I mean the scare
value, the float created. But here we need to bind not the value directly because as I explained in
the previous video, we are doing it by progress, and our progress is 0-1. So if we go and bind
this value to score, as I did right now and
compile and press play. It is currently at zero, and the moment I
score any points, it will be filled up to
the complete full because our value of one means 100%. So we need to make sure we
create a new binding for this. And this new binding
will get our score. And let's say let's create
another floss value and call it let's say score goal. So this is the score we are trying to reach to end the game. Usually, you would not do
it directly in the widget. You would get this value
from game mode or somewhere else where your logic is dictating how many
points you need, but we are not going to apply multiple levels with
multiple logics, so I'm just going to
keep it very simple. We need ten points for this game to be considered
complete, like level finished. And as such, what
we are going to do, we are going to
compile it and put the default value of
score goal to ten. Now, we need to get a
percent of this value. You could try to
search as percent, but this is just a text. It is converted to text. So what we are going to do
instead is we're going to take our value and we are going
to divide it by score. Sorry, multiply it by
score and divide by 100. So we multiply it by score, 100. Sorry, we multiply by score, and we divide it by 100. This should give us the value. Unless I misremembered
how percentage works, this should give us
a value we need. Let's test it out. Now, every time I put
in another sphere, I will get one more
bar of progress. Because each time I
get a score, now, it gives me 10% of the bar, which is exactly what we wanted. And if I were good at this game, I would perhaps do it easier. Anyway, so now we have our
second widget working. And the only thing
we really did, we just added this float
percentage calculation, and we add a variable
that is our end goal. We could get this
from game mode or game instance or whatever
actor you are making that needs something to happen or widget to react
to be more specific. But that's not necessary for our minigame so we're
going to leave a set. Next, let's take a look at here. We have time. If your game has time
related elements, let's say you have
a racing game, you have a you need some kind of time
ticking UI mechanism, this is how we are going to
make it in the next video.
29. Timer: Welcome back. In this video, we are going to convert this widget placeholder
we have here into an actual timer
that just ticks up. Now, the issue with
this doing this is the timer is something
that happens in every tick. So ideally, you
wouldn't want to have a lot of timer actions, because if you go to event
graph and we get our tick, This needs to trigger essentially every second and update our value for the timer, which is ideally is not
something you would want. And if you are doing this, regardless, it's better to probably have some
way to stop it, the tick process when
you don't need it or alternative ticking options if it's related to some kind of event or something so
that you can enable disable this tick you could even add a
timeline if it's just 10 seconds or 20 seconds, so you don't have to worry about Evan taking
every single time. Evan Ts adds a lot has a lot of cost when
there are too many of them. Now, for the purpose
of this, let's go. We have this time here, and we need to bind this. And before I forget, let's make sure we rename
the previous one. G score, get percent. We already did. So let's create a new binding. For this time. And this is going
to our new binding, and let's name it time elapsed. Time elapsed. Now this function is
supposed to give us a text value of a time
that already has passed. So we are going to
create a variable, call make sure it's float after. Let's call it time let's convert it to float
and add this value. We need to update our time value by the game
time in milliseconds. So let's get Delta time. And what Delta Time does, Delta Ts is amount of time passed after
essential game has begun. So if you plus this by
Delta Delta Time and set, easier to do it
like this and set it and we input this as a text value.
Let's see what happens. 1 second. Context. Oh, this is not the correct Delta time. We need a Delta time for this
get world Delta seconds. Which is quite confusing with their naming being so similar. But anyway, so our
widget is way too up. Let's make sure you
can actually see it. And let's see position wide
let's put it somewhere lex. Compile, press play. So now we have a
time that's ticking, and it will keep ticking. But this is not what
we want exactly. So what we are going to do, we are going to convert this time to time seconds to string. This will automatically
convert it to the format of
minutes, et cetera. So now, seconds, minutes
now we have a time on top. You could also make
a countdown timer, for example, if you want
to have, let's say, 20 seconds to score a point, and if you don't score a point in seconds, you lose the game, et cetera, or if you want to just have a max amount of time they can spend
in a certain level, you can do it anyway you want. If you want to
turn it countdown, all you would need to do would
be to subtract this value, get rolled out of seconds and
apply this value instead. And you would need to set a
default value for time to the amount you want it
to be the max second. So let's say if I want to
have 30 seconds at max. So I make it 30 seconds, and now my time is going out, I have only 22 seconds. Obviously, we don't have
any logic applied to it to actually game
over or whatever, and we don't really want it in this case, so I'm
going to remove it. And now, what we could
do is also if you don't want it to be so
jarring in a way, if you don't want this float
value at the very end, all we need to do is do the same thing I
previously mentioned. We convert instead of
using float values, we use integers, and I'm just going to
demonstrate a simple one. We're going to give
time. We're going to convert it to integer. We're going to put this a time. And actually, what
we can do instead is convert this to integer. Conversion. Oh, not this fun. Let's just do this.
It will be faster. And we set this value
and we put this value as 2 seconds seconds to string. That was a weird error, but
now we get this by second. You may notice it is
still not what we want. We still have dot zeros. So what we can do instead, we can remove this and remove
this as well, turn gates. If you remember our
previous function, the way I showcase you, we
have this apparent and we had to text float here. So what we can do instead, we have to text
string here anyway, but we want it to be
from float to string. What you could do is you
could create an append by, let's just copy our append nodes so I don't have to type it. So what we could do
is we just append and make a combination
of appends to be like, Oh, okay, this first
time value is minutes, the second time
value is seconds. By that, we would need
to clamp, divide it. Every time it's
reached 60 seconds, you set it to zero,
you put it in a value. You can multiple ways. If you don't want that zero
there just to be clear. And obviously, if you
know C plus plus, you can also edit the
Ciplus plus functionality and make a one where it does
exact same thing as this, but urnicate less two values. And we could also always
just remove part of the string to make it so that they don't have
any fractured values. But I personally don't care. I don't mind time
having milliseconds, especially if you're a
speed runner or something. Let's make sure we put our
time value back to zero. We start at time zero, and we delete our integer,
compile and save. Now we have a widget that
tells us the time passed. We have our progress var, our total score, all of
them are misaligned, sadly. So I will have to align them if I want
any visual clarity. So let's put 20 just a bit. I want endpoint of it to
be the same as score. Yeah, actually, good enough. Not ideal, but it
doesn't have to be. We're just prototyping stuff. And now we have our timeline. We have our score. We have our progress bar. Now let's change
our speed value. Now, this one is going
to be a bit different because the speed we are getting is from the
third person character. So the movement we are trying to get the velocity of the
third person character. So what we need to do, let's say, check sorry. Velocity. So what we are going to do, we are going to
calculate velocity. And as you can see, this
is not what we need. This is not an
output we can use. So instead, what we are going to do For all intended purposes, we could get easily
our current velocity from Sirt person character
inside star blueprint. But this is not what
we want, really. In a game, usually you would have in a game where you
would want to see your speed, usually you would have
some kind of value for it. For example, if you
are driving a car or it is a game where you are calculating
speed or whatever, when you are flying, would have some kind of
floss value already attached to it
that would dictate how fast your character
goes or does not go. In this case, we don't have it. We are just using unreal
basic movement system, and what we can do is
we can get our speed. If I 1 second, get my question. This is going as parameters, so it's also not correct. So we are going to do we are
going to event graph here. And in event graph, by the way, if you have noticed
we did not use this tick we had before we will, make sure you delete it
if you don't need it. This adds cost just by existing. We are going to go to speed, and we are going to
create a new binding. And we are going to
call this binding where we are going to get speed. Now, the speed we're trying to get belongs to the
player character, and I will show you how it's
done in the next video.
30. Additional Functions: Welcome back. Now,
continuing on, we are trying to get a value for our speed we are going to have here on the bottom right
on the top of the widget. We need to get the
movement speed of our third player character. And as I have shown in
the previous video, there is no direct
way of getting like, Oh, get me the movement speed. We need to go
through some poops, and I'm going to move it from third person player character
into the widget itself. So if I want to modify
widget properties, I can just do it from widget. What we are going to do, we are going to get player character. And the reason why we are getting this player character is because we are trying to find a speed for the
player character. If you were trying
to get for some kind of enemy or object in the level, what would be ideal is to get the value directly
from that object and somehow transfer
it to the widget via interface or game mode. Instance, if it's necessary, usually it's not a good idea to have all these calculations constantly happen unless it is integral part of your game, you should probably not do it. Again, it's a lot of cost
for a very little return. But again, in some games
it's required, so you do it. So we need our player speed, so we are getting our
player character, and what we need
is its velocity. If we get velocity and we have here at the
very bottom, get velocity. And if we just put
it into return, and compile press play, you will see we are
getting XYZ values because velocity
is usually well, not usually is
calculated in XYZ. We're moving at a
certain velocity, X at XY or Z in the three D world. But
this is not what we need. Like we don't want to put
our XYZ into the viewport. So what we need to do we
need to get vector link. And now this value is our speed. Let's see, press play. And now, this is our speed. You may be wondering
why is it getting stuck at 3,000 and why it's
moving slower, going up. First of all, we do have a fractal value at the
very end, which is normal, but you may notice also we
have a max speed of 3,000, and that happens because
of the blueprint, character movement
and the max speed we have sent previously. So our max vax speed is 3,000. It is 3,000 centimeters. It is essentially
30 meters/second. Now, we don't want it to be directly put in
that kind of value. So what we are going
to do instead, we are going to convert
it to text to text. We are going to make sure
we don't have fractals. I don't want them
in my UI for speed. And for their own,
before we even do that, I will divide this value by 100 because I don't want my speed to be
shown in centimeters. I want it matters. Now, what this is going
to give us is a value of one to 30 being our speed. Sometimes it goes a
bit far up because I'm flying and stuff, but
that's understandable. This is just calculating
my total velocity. So now we are going to do something we already
did in the previous one. We are going to append We're going to append the
value and after the value, we are going to add
let's make less. And I will add extra
space the spacing. I'm going to put it back in. I will compile it,
save it, press play. And now I have a widget
that tells me my speed. There's a lot more you
can do with widgets. So Widgets also act
like menu elements. So if you want to
click a button or, you know, manage your inventory, check the map, click
on the map elements, et cetera in the games, you would need some kind of interactability with
widget directly. And usually we would create different widgets
and apply them, remove them from the scene like screen as you need them or
by removing the widget. So for example, we have our widget here,
created this widget. We could also
eliminate the widget. So Widget if you go to
the widget commands here. You have removed from parent, you can use to just remove it or set visibility to invisible or just move it
out of the screen. Ideally, if it's a widget that is CPU consuming, et cetera, you would want to just
remove it entirely. So's remove and if you read the description, it is removing it from
everything, essentially. It's removing from
containerus, et cetera. Unless you need it, you should probably remove it. And in our case, this widget is something that should
remain on the screen always. You may want to if you want to hide certain elements
of the widget, you can do that
within the widget itself by adding some calls, et cetera, by going to the widget and calling
direct events. We have our Widget
UI reference here. So if I want to, let's say, get a certain function. Let's we had the one for time. So we have co function
time elapsed. So you are able to access
your widget element, like functionality
by the reference we have here when we
create the widget. So you can always just
manage your widget elements, hight specific parts of it or elements just by casting to it. Sorry, just by using
the reference from it. Now, if you want to click create some kind
of interactivity here, what we would need to
do is, for example, we could just add a bottom I'm going to
add a button here. And on this button, I would add an event
called On clicked. So when this button is clicked, something is supposed to happen. So I'm just going to
make a print string. And here we go. And I want it to say hello
when I click this button. Compile, PrescoPlay press play, and as you can see,
I can click on it. But when I begin my game, I would lose my mouse input. The reason I was able
to click it because when I play, I
still had my mouse, but you wouldn't have this
mouse when you actually begin the game if you're playing
with a keyboard, et cetera, because this is
only going to work inside unreal Editor
until I click this. And now if I want to
click the widget again, I need Fight and
click this here. But this is not the way it
would work in the game, especially if it's a widget that spawns in the
middle of the game. To make sure you can actually click on this,
what you would do, the widgets that require
your ability to be clicked on would have an event
that lets you click on it. So I will add an event called Construct me and my miserable
typing event construct. What this does is gets triggered when the
widget is created. This is this by no means should be part of
the UI widget elements. I'm just showing it here so
you know how it is done. Ideally, you would create
this in a different widget. So when event is contracted, we get player controller. Let's move it. And and set mouse Wait. This is not it. My apologies. We need to get player
controller from this, not from execution bits. This is just a pure function. And here, what we do is
we get mouse cursor. And we make it and compile, press and press play. So now, while this widget is on the screen or not while it is when this widget is
beginning to create, I still have my inputs
available to me on my keyboard, but I can also click on this button and create
the Hello button. But obviously, imagine this
being an inventory or a map, et cetera, and you don't want it to be constantly
on screen, correct? So you would want to
disable this mouse input and remove that element of
the widget from the screen. So first of all, let's anchor this so it's not in the
middle of the screen. Yeah, much better. So when I press play now,
this is now bottom right. First, now that it's done, let's take this widget. And we know this widget
is our Button 01. Let's go to our Button
01 and here get. Instead of selling hello, we're going to let's see
what we can do with this. This is just a widget, so
we can, I guess, remove it. Yeah. So let's see what
happens when we click it now, when we remove it from the
parent, and it's gone. But we still have our mouse
in the middle of the screen, obviously that's
quite an easy fix. We get this mouse cursor
and we set it to fs. And target should be player
controller, obviously. And when we press Play now and click on this button,
it now disappears. Now, this is useful when
you have, let's say, a UI that you want to have a click on that
has something like, let's say, when you
have a certain item, it show up in your UI. You click on it, you consume
it, and it disappears. Obviously, you could write all down logic to it, like, Oh, if you don't have anymore
of this item, remove it, or if you like, time passed, it expired. It's up to you. You can create
whatever you want with it. But I personally don't need this functionality in this one. And as such, I
removed all of it. But just keep in mind. That's how you can create
your menu elements. You can put a text, you
can click at buttons. You can add a grid, which is if you go
to our Canvas here, we have our grid
panel, for example. And inside this grid panel, I can add multiple other things. So I can add buttom one, button two, button three. It's hard to see right now, but you will see it in a second. And I will just size them up. I can put them in rows. And now I have four buttons. In a different row. I can move them
around if I wanted. As you can see. Now, if you want your size to
be bigger, et cetera, you would just do it
in the grid panel, we are going to size
content itself. So it's only going to be
the size of the content, or you can instead go to your buttons and
from the buttons, you can change how
they are padded, they are past, et cetera. And you are not limiting
to just adding buttons. You could add an
image here as well. And if your image is, let's say, Wait.
This is not image. This is an HDR image. My boologis. Let's just add
a texture, regular texture. And this texture is very big, so it's suddenly covering
the whole widget. You can reduce the size. If you want, and in my case, I don't want any images, so I'm just going
to kip the buttons. If I go to grid panel, you will see we
have our size here. I'm going to increase the
size to something like this, and we can position
it where you want. I'm going to anchor in
the bottom left for now and position it 000 and then move it around as I want something like
here, which is fine. Now we can click on the buttons. We can change their
colors if we want. I understand it's kind
of hard to see from here and So we have our columns. We have our rows where we
want this to be placed. And keep in mind,
this is a grid. So there are like this
is a grid based system, and there are
buttons on the grid. If you want menu elements that are more in line to
what you are used to, what you can do is 1 second. I believe it was this one. And if I add buttons here, yes. If I add buttons here. Now, I want them to be
horizontal, not vertical, so Sorry, I want them
vertical, not horizontal. Now I have them horizontal. No, I'm just going to
paste this bottom. And now I have five
UI elements spaces inside this overlay, and I can add texts on top of them if I wanted to do each one. And let's say, this
one is start game. Yeah, not star game, you got the point. Options, quit game like extras, et cetera, whatever you want
from your game Stack box. Feel free to experiment. There's a lot of
things you can do. Imagine any game you have
ever played or have seen, there you eyes and try to think about how
they made it happen. How did they how would you use the widget
system in unreal to get the same results and whether it would make
sense for them to be in the same widget or part
of a different widget. Also, do keep in mind, you can add other widgets
into your widgets. So if you have a
different widget, which we are going to
create in a second. Again, just for
demonstration purposes, I will not actually we are going to click
and create a widget, and we're going to call the
user widget and go Cty. That's just SS, just so
I can find it easily. And here, if I want
to add a widget, I could just add it here. And I have my SS widget here. And if I open my SS widget now, and in this here, I add a panel, I
just going to add a canvas just
because it's faster. And I'm going to add an
image or actually a text. I'm going to anchor the text
center and just type text, compile, press save, let's play. And you may not on the
top left, I have SSSS. I anchored it here. You may
ask why is it not here, and on the top left gal I
have not anchored it here. I anchor it here in the
center as well and position it So you see now, I have a widget inside a widget, which is useful when you have inventory system or some kind of menu that overlays itself, like a menu with multiple
layers and stuff. That is very useful. Also, it lets you code them independently of each other and you may remove them
when they are not needed, et cetera, or if some widgets are specific to certain levels, you can use them there and
remove them afterwards. There are a lot of ways
you can use your widgets, and widget system in
general is very expensive. Like there's a lot of
stuff here you can use, but that you would just need to test it out to see
what you want to make. And there is no one
solution to all. You can add a circle
trober, et cetera, which is just a nice
widget. I like using. You can use this like
loading screen or whatever. You can add more
elements, less elements. Like, imagine you make a
game and the amount of dots represents the
amount of HPs you have. You can just increase
them or decrease the amount with the
amount of HB you have. There's a lot you can do.
Imagination has no limitations, so feel free to experiment. That is going to be all for widget introduction in
this basics course. We will have more in depth explanation
about widgets and how to make complicated
game elements in the intermediate course which will be released in the future. I hope you learned something and you enjoy your time here. If you have any questions,
feel free to reach out. I will do my best to help you. Thank you, and I hope
you have a nice day.