Creating HUDs using C++

Now that we have almost all of the gameplay finished for BountyDash, we need to be able to report the current game state to the player. We are going to do this in a similar way to that of Barrel Hopper; however, this time we will be creating our HUD object entirely in C++ code. HUD objects in UE4 utilize something called a Canvas. A Canvas is simply a draw area within the screen that we can use to do things such as draw text, images, and other HUD-related imagery. On our HUD object, we will be displaying the player's current runtime and the player's current score.

ABountyDashHUD

Let's start by creating a new HUD object via the C++ class wizard found within the editor. Create a new class that inherits from HUD and call it BountyDashHUD. Once the code has been generated, open the BountyDashHUD.h file. Ensure the class definition matches the following:

UCLASS()
class BOUNTYDASH_API ABountyDashHUD : public AHUD
{
    GENERATED_BODY()
    ABountyDashHUD();

    UPROPERTY()
    UFont* HUDFont;

    virtual void DrawHUD() override;
};

In ABountyDashHUD, we have included a constructor, a UFont handle that we will use to save the font we wish to use for onscreen text, and we have overridden the DrawHUD() method. This will allow us to specify custom HUD drawing functionality so we may draw our text to the screen.

Before we begin to define this object, we need to create a font object that we can use for our screen text. In the content browser of the editor, create a font object that is exactly the same as the one we created in Barrel Hopper; however, this time call it BountyDashFont. The settings for the font should appear as follows:

ABountyDashHUD

Now navigate to BountyDashHUD.cpp and add the following code for the HUD constructor:

ABountyDashHUD::ABountyDashHUD()
{
    static ConstructorHelpers::FObjectFinder<UFont>OurHudFont (TEXT("/ Game/BountyDashFont.BountyDashFont"));

    HUDFont = OurHudFont.Object;
}

This constructor simply initializes the HUDfont handle we declared earlier to that of the custom font we just created. Next, add an empty definition for DrawHUD(). We will come back to this shortly:

void ABountyDashHUD::DrawHUD()
{
}

Getting information from our objects

Before we define the DrawHUD() method, we are going to require some information from the ABountyDashCharacter and ABountyDashGameMode objects. We require the score from ABountyDashCharacter and the runtime from ABountyDashGameMode.

Let's start by modifying the ABountyDashCharacter so that we may get the score. Navigate to BountyDashCharacter.h and, in the class definition, add the following method under public:

int GetScore();

This accessor method will be used to retrieve the player score. Now we can navigate to BountyDashCharacter.cpp.

Add a function definition for the method we just declared:

int ABountyDashCharacter::GetScore()
{
    return Score;
}

Now we must add a runtime clock to the game mode. This is a very simple process. We simply have to add a float member to ABountyDashGameMode and increment that float value every frame by the delta tick to accumulate the time passed during a game run. Navigate to BountyDashGameMode.h now and add the following protected member:

UPROPERTY()
float RunTime;

We also need an accessor method for this member and, if we have not already, to override the Tick() function so we may have our game mode tick. Add the following public methods to the ABountyDashGameMode class definition:

float GetRunTime();
UFUNCTION()
virtual void Tick(float DeltaSeconds) override;

Now navigate to BountyDashGameMode.cpp. We are going to write the defines for the Tick() and accessor methods. Add the following code to BountyDashGameMode.cpp:

void ABountyDashGameMode::Tick(float DeltaSeconds)
{
    RunTime += DeltaSeconds;
}

float ABountyDashGameMode::GetRunTime()
{
    return RunTime;
}

Setting the HUD class in the game mode

While we are working with the ABountyDashGameMode, we should add code to the constructor of this object so that our new custom BountyDashHUD is set as the default HUD class for this game mode. Within ABountyDashGameMode::ABountyDashGameMode(), add the following code:

HUDClass = ABountyDashHUD::StaticClass();

HUDClass is a member found in the AGameMode base class that is used to identify which object type we wish to use as the game HUD. In our case, that is the UClass type returned by the StaticClass() method found in ABountyDashHUD. Also ensure you add the appropriate include for ABountyDashHUD to the include list of the BountyDashGameMode.cpp.

Implementing a custom DrawHUD function

Now that we have the means to access all of the information we require, we can write our DrawHUD() function. Navigate back to BountyDashHUD.cpp and add the following to the include list at the top of the .cpp:

#include "BountyDashCharacter.h"
#include "BountyDashGameMode.h"

Now we are going to add code to the empty DrawHUD() function definition. Begin by adding the following:

Super::DrawHUD();

FVector2D ScreenDimensions = FVector2D(Canvas->SizeX, Canvas->
SizeY);

ABountyDashCharacter* DashCharacter = Cast<ABountyDashCharacter>(UGameplayStatics::GetPlayerPawn(
GetWorld(), 0));

ABountyDashGameMode* DashGameMode = GetCustomGameMode<ABountyDashGameMode>(GetWorld());

Here, we are calling DrawHUD on the super class so that we do not lose out on any of the base DrawHUD functionality found in the AHUD parent class. We are then getting the screen dimensions from the Canvas object mentioned previously. If you cannot remember what a Canvas is, it is simply an object that represents the draw area we have access to when drawing content to the HUD. It is from and through the Canvas object we can perform actions such as getting screen dimensions, drawing images, and drawing text. The default Canvas object is the entire screen space available and will be the object we use.

We are saving the screen dimensions in a FVector2D. Next, we are attaining a handle to both the game mode and the character. We are going to be using these handles to retrieve the information we specified previously. Next, we are going to generate the FString that will hold the text we are drawing to the screen. Add the following code:

FString HUDString = FString::Printf(TEXT("Score: %d Runtime: %.4f"), DashCharacter->GetScore(), DashGameMode->GetRunTime());

Here, we are utilizing the printf functionality of the FString object to generate a text string. As you can see, the %d character will be replaced with the game score retrieved from the DashCharacter handle we retrieved earlier. We then use %.4f so that printf will only pull four decimal places from the floating point value we are using to hold the game time. If you are unfamiliar with printf semantics, I strongly suggest looking up the stl::printf functionality set so you may use the similar FString::printf effectively.

Now that we have the string we will be drawing to screen, we need to inform the HUD to draw this text. We can do this with a very simple function. Add the following code to DrawHUD():

DrawText(HUDString, FColor::Yellow, 50, 50, HUDFont);

This function takes in an FString to use for screen text, a color value to color the text, screen position co-ordinates (in this case, 50 on the X and 50 on the Y), and a font object to use. This will draw our generated text to the screen. Compile and build the project then run the game. You should see the following in the top left-hand side of the screen:

Implementing a custom DrawHUD function
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.29.219