♪♪♪
Lauren Ridge: Welcome back.
In the last video, we set up our batteries to shoot electricity
between themselves and the character when they are picked up.
We are going to add another visual element now.
We are going to work towards a HUD
that will display our character's current power,
as well as the power needed to win the game.
This is building towards a win state,
a lose state, and the general playing state in the game.
Let's close all but the CollectionLevel tab
to make more room when we start working on the HUD.
Open Visual Studio and go to the BatteryCollectorGameMode.h.
We are going to set up a power to win variable.
If we have a bar to display how much power we need,
then we need to know the maximum of the bar in order to win the game.
This is going to be a protected variable.
We only want to be able to change the variable
from within our GameMode or classes derived from it.
[Refer to code onscreen]
The keywords on DecayRate will work for this. Add the Meta keyword as well.
[Refer to code onscreen]
Copy the UPROPERTY() line and paste it above PowerToWin
because we want the same property flags on PowerToWin.
Add a comment. "The power needed to win the game".
Again, this is on the GameMode because that is where the rules
of the game should go, including how to win the game.
We are going to get a public function to return what the PowerToWin is
because this is needed by the HUD.
The HUD is going to be based on a different class.
The HUD needs to call this PowerToWin function to know the power needed to win.
[Refer to code onscreen]
It is a constant because it is not going to change anything about the
power, it is just going to return the value.
It is going to be a UFUNCTION() so we can call it in our Blueprint.
We will make it a BlueprintPure function because it is not going to change anything,
it will just tell us what the PowerToWin is.
[Refer to code onscreen]
Add a comment. "Returns power needed to win - needed for the HUD".
We are going to set GetPowerToWin in BeginPlay().
We can't set GetPowerToWin in the constructor because our
GameMode may not necessarily be constructed after our Character is constructed.
We need to base the PowerToWin on the Character's InitialPower.
We are going to do it in BeginPlay() because that means
everything will already be spawned and registered.
We need to override BeginPlay() to do that.
[Refer to code onscreen]
This is similar to when we overrode Tick() before.
Some functionality is already provided,
but we need to hook into when it is called.
Go to BatteryCollectorGameMode.cpp source file.
We will do this at the top because BeginPlay() will happen
before Tick(), but after the constructor.
[Refer to code onscreen]
We will call the parent BeginPlay() in case anything happens
on the GameMode that we need to make sure still gets called.
Add a comment: "set the score to beat".
We will set the score to beat on the current Character's Initial Power.
To do that, we need to get the GameplayStatics.
We already have Kismet/GameplayStatics.h included.
We can copy the line below in Tick() where we get the MyCharacter.
Paste it below BeginPlay().
Like below, we need to still check if MyCharacter exists
[Refer to code onscreen]
and is the class we want to cast to and there is not some other Pawn.
[Refer to code onscreen]
We can tweak this value, make a variable out of it, and set it up on the constructor.
To test, we are going to multiply and say you need at least 1.25
times your Initial Power to win the game.
Again, we used the same ABatteryCollectorCharacter cast
below in Tick() to save on typing.
If that is true, we can use that value to set PowerToWin.
We want to display that in a HUD.
Before we start making the HUD, we need to change
some of the dependencies in our build file.
To find your project's build file, go to the
Solution Explorer and select ProjectName.Build.cs (BatteryCollector.Build.cs).
If you notice, you already have some PublicDependencyModuleNames.
We are going to add some things so we can use UMG (Unreal Motion Graphics) here.
We need to add UMG into this list.
Add UMG if you want to add any UMG widgets or HUD to your game.
If UMG is new to you, there are some tutorials online for using UMG with C++.
You can definitely check those out and then come back to the video.
Then, we are going to add some private dependencies.
[Refer to code onscreen]
You can follow the format as above because it is the same.
Depending on your engine version, sometimes templates already have this commented
saying if you want to use Slate, then uncomment this line.
This line is going to follow the format as above.
[Refer to code onscreen]
[Refer to code onscreen] We are going to add Slate and SlateCore
because UMG requires some of these Slate modules.
We need to go to our project header.
Select BatteryCollector.h.
Do you see where it says '#include "EngineMinimal.h"'?
If you started from a blank project or something that wasn't a template,
this is going to say "Engine.h" and you will be ready to go.
Some templates have EngineMinimal.h set instead of Engine.h.
We will change EngineMinimal.h to Engine.h, which means we will have access
to more header files so this will compile correctly.
Finally, we need to go to back to our GameMode and make some variables
to hold our widget. Then, we will write some code to set the widget.
Go to BatteryCollectorGameMode.h header file.
Go to the protected variables section.
We need a protected variable for the widget and for the widget instance.
You have seen a lot of the formats we are about to use,
but I will go through them again.
[Refer to code onscreen]
We can use a forward declaration because we don't necessarily need to work
with the widget yet.
[Refer to code onscreen]
The TSubclassOf is similar to the UCLASS(), but it is restricted to only
things which inherit from UserWidget.
This script is the specific instance of it that will be spawned and created.
Copy the line for UPROPERTY() and paste it
for the HUD WidgetClass so it is EditDefaultsOnly.
We can only change it on instances.
We can change it in the Blueprint.
HUDWidgetClass is also protected like the previous variables.
We want to make CurrentWidget a regular UPROPERTY() so it is
handled properly with garbage collection.
We are not going to manipulate CurrentWidget outside of code,
so we don't need any other keywords on it.
Add a comment. "The Widget class to use for our HUD screen".
Add a comment. "The instance of the HUD".
This is one copy based on HUDWidget class.
Once we spawn it in, we can directly interact with CurrentWidget.
I am getting IntelliSense errors.
Let's see.
No, that looks okay.
CurrentWidget is one copy based off the HUDWidget class that is there.
IntelliSense has caught up with us.
Finally, we are going to the BeginPlay() we just set up.
After we have set PowerToWin, we will set the widget to use.
[Refer to code onscreen]
This is similar to when we did the spawn volumes.
We want to make sure we have set something on the class variable.
[Refer to code onscreen]
We are going to GetWorld
and then use the HUDWidget class, which is why we have to make sure it is not null.
If you notice, UserWidget has the IntelliSense
underneath it. We have to include it at the top.
Now that we are making a widget and need to know what it is,
we have to include it and be able to know more about it.
This is why we include the header file Blueprint/UserWidget.h.
I looked up the folder UserWidget is in, which is the Blueprint/UserWidget.
IntelliSense should catch up in just a minute.
[Refer to code onscreen]
It is fairly simple to set up a UMG widget.
Then, we will go into UMG UI Designer in the next video
and lay out our UI with our health bar.
We are going to compile.
In the next video, we will set up the HUD and we will be able to set up
the bar showing how much power you need to earn to win the game.
Thanks.
♪♪♪