When we are learning to program or trying to find an error in the code, it is very useful to print some messages on the screen or in the log to check if the code is running as it should.
Before showing the functions of the messages, I will talk about the FString type of Unreal Engine. This type is used to represent a sequence of characters. We used the FString type in the game in Part I to draw the player's information on the screen using the AHUD class as seen in this article:
TutoProjectHUD class: Drawing on the screen
The FString class has a function called Printf() that builds an FString from formatting text and other parameters that are inserted in the text. The example below shows the use of Printf():
FString PlayerInfo = FString::Printf(TEXT("Rank: %d - Name: %s - Health: %f"),
3, TEXT("Romero"), 0.4);
/*
The PlayerInfo variable will have this content:
"Rank: 3 - Name: Romero - Health: 0.4"
*/
The formatting text contains special characters that start with % and will be replaced by the values of the other parameters in sequence. The special characters represent different types of values. In the example, these characters were used:
- %d: Used for integer values in decimal format.
- %s: Used for strings (sequence of characters).
- %f: Used for float values.
Be careful when using %s with FString variables. You need to place the * operator before the variable name, as shown in the example below.
FString Name = TEXT("Romero");
FString PlayerName = FString::Printf(TEXT("Player: %s"), *Name);
To show a message on the screen, you can use this code:
if(GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 8, FColor::Red, TEXT("Test message!"));
}
Let's look at each part of this code:
- GEngine: Pointer that represents the Engine. To use it you need to add the line #include "Engine/Engine.h" at the beginning of the cpp file.
- if(GEngine): Before using a pointer, you must verify that it is valid. If GEngine is a null pointer, the if expression will be false and the code inside the if will not be executed. If GEngine has any other value, the if expression will be true and the code will be executed.
- AddOnScreenDebugMessage(): Function of the UEngine class that shows the message on the screen.
- -1: The name of this parameter is key. If you enter a positive value, the previous message with the same key will be removed from the screen.
- 8: This parameter indicates the time in seconds that the message should be visible on the screen.
- FColor::Red : Color used in the message.
- TEXT("Test message!") : The message that will be written on the screen. It can be a variable of type FString.
The Unreal editor has a window called Output Log that can be accessed from the menu Window > Developer Tools > Output Log.
To show a message in the Log, use this code:
UE_LOG(LogTemp, Warning, TEXT("Test message!"));
LogTemp is a category of Log already available at Unreal. Warning is the level of the Log message. Warning level messages appear in yellow and Error level messages appear in red. The message parameter accepts special characters in the same way as the Printf() function.
Example usage:
Create a C++ class using Actor as the parent class. Use the name MsgActor for the new class.
We will use a Scene Component as the Root Component so that the Actor has a Location. In the MsgActor.h file, add a pointer to USceneComponent below the constructor declaration.
public:
// Sets default values for this actor's properties
AMsgActor();
UPROPERTY(VisibleAnywhere)
USceneComponent* RootScene;
In the MsgActor.cpp file, inside the constructor, an instance of USceneComponent will be created and the reference stored in the RootScene variable. Then the RootScene is defined as the RootComponent of this Actor.
AMsgActor::AMsgActor()
{
// Set this actor to call Tick() every frame.
PrimaryActorTick.bCanEverTick = true;
RootScene = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
RootComponent = RootScene;
}
Still in the MsgActor.cpp file, place this code in the BeginPlay() function:
void AMsgActor::BeginPlay()
{
Super::BeginPlay();
FString Message = FString::Printf(TEXT("BeginPlay of %s - Location: %s"),
*(GetName()), *(GetActorLocation().ToString()) );
if(GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 8, FColor::Red, Message);
}
UE_LOG(LogTemp, Warning, TEXT("%s"), *Message);
}
The GetName() function returns the name of the instance. The GetActorLocation() function returns an FVector. The FVector type has the ToString() function that converts the contents of an FVector to an FString.
Compile the code and add an instance of MsgActor at the level. Start the game and see the messages on the screen and in the Output Log window as shown in the images below.