Logging In UE4 CPP (C++)

Logging in C++ in Unreal Engine comes in multiple varieties, and determining how to insert variables into your text can be tricky for newer Unreal Programmers. This guide should step though the following:

  • Log to the Output Window

  • Text Formatting With UE_LOG

  • Create Your Own Logging Category

  • Log to the OnScreenViewport (Blueprint equivalent of PrintString)

Some things, such as text formatting with variables is the same regardless of the output method.

NOTE :: I have a quick guide at the bottom of this post, for those looking for quick-reference.

Logging to the Output Window

Unreal contains a macro that allows you to quickly and easily output text to the output widow. This can be done via:

UE_LOG(LogCategory, LogVerbosity, Message);

Here, there are three parameters, the first being the LogCategory. This helps to separate the purpose of logs when filtering, and also contains some verbosity information. There are many categories already defined that you can use, the main one used is LogTemp, meaning that it’s a temporary log that doesn’t have anything particularly special about it. However, there are many other categories such as:

  • LogTemp

  • LogInit

  • LogLocalization

  • LogCore

  • LogMemory

  • LogProfilingDebugging

  • LogSerialization

  • LogLoad

  • LogRep

  • LogNet

  • LogFunctionalTest

  • And many many more

I typically just use LogTemp for all of my logs, as I like to keep mine separated from the other categories that Unreal is using. In my mind, if it uses one of these LogCategories, I like to know that it’s coming from the Engine vs my own code.

The second parameter determines the logging level, which determines the verbosity of the message. The lower the verbosity, the more critical the message is. Different logging levels come with different formatting, Warning for instance will display yellow. Here is a list of the Logging Levels;

  • Fatal

  • Error

  • Warning

  • Display

  • Log

  • Verbose

  • VeryVerbose

This allows you to assign how and when it should show this log. If you then set your logging levels to Warning, then only logs at Warning and above will be printed (Warning, Error, Fatal).

The third parameter is the actual message! Simple as that.

You specify the message using the TEXT() macro.

In the end, a sample log may look as follows:

UE_LOG(LogTemp, Display, TEXT(“Test Log”));

Formatting Text with TEXT for UE_LOG

Now, printing a text literal is all good, but what if you need a dynamic string? Such as : “I have {numItems} items”. Well, this is made very simple in Unreal! using the UE_LOG and some text formatting, you can specify these parameters and have them print in-line like so:

UE_LOG(LogTemp, Display, TEXT(“I have %d items”), items.Num());

This will take the %d and swap it out with the value of items.Num(), if you had two parameters, they would just evaluate in-order. The catch here is that %d will not work for any type of value %d is meant for integers only, if this was a floating point value, you would need to specify %f as opposed to %d.

Here is a list of some text formatters:

  • %d - integer

  • %f - float

  • %s - *string (FString)

If you need to print a boolean value, first convert it into a string and then print the string as such.

UELOG(LogTemp, Display, TEXT("result was %s"),(result ? TEXT("true") : TEXT("false")

Plesae note that when printing an FString, you must specify the address of the string and not the value itself. Example:

UE_LOG(LogTemp,  Display, TEXT("%s spawned in an ItemBounds object! Current Overlaps is %d"), *item->nameTag.ToString(), item->itemBoundsOverlaps);

You can see that simply adding * before the variable will convert it properly.

Create Your Own Logging Category

As I mentioned above, it may not be great to use Unreal’s premade logging categories, you may want to be able to easily see everything from your player inventory. Luckily, making a logging category is incredibly simple! You simply need to define the LogCategory in two locations, one in the header file of whatever file you would like to use it in, and one in the cpp file.

In the header file, populate this macro:

DECLARE_LOG_CATEGORY_EXTERN(CustomLogCategory, LogVerbosity, CompiledVerbosity);

Then, in the cpp file, use the following macro:

DEFINE_LOG_CATEGORY(CustomLogCategory);

Taking care to use the SAME name as defined in the header file.

Filling out this macro should be very simple the parameters are as follows:
First parameter is the log category name. Name this whatever you like, and use that as the category when logging.

The Second Parameter is the default log verbosity, I would advise (unless it’s a specific category) to keep this at the Log level.

The Third Parameter is the default verbosity level that will ever be compiled into the game. If this is set to anything above VeryVerbose it will not be possible to change the verbosity to a level below what’s set here. Also, there is a macro defined to be All, which will compile for all the of verbosities in default unreal (Very Verbose to Fatal).

I would just stick with the basics and set it up with a log verbosity of Log, and a CompiledVerbosity of All. As such:

DECLARE_LOG_CATEGORY_EXTERN(CustomLogCategory, Log, All);

On Screen Logging (CPP PrintString Equivlent)

If you would like to use the on-screen logging system, unreal actually makes this a breeze as well, with a function that is easy to call. The rest of the funcition should work similar to a blend between the Blueprint and the UE_LOG.

GEngine->AddOnScreenDebugMessage(OrderIndex, DisplayTime, Color, Message)

Here, there are more parameters, but all should be quite simple apart from the OrderIndex. The OrderIndex is simply an index that you can define to override the order to display this message in, if you always want it at index 0, specify 0 as the index. To display in the typical “order recieved” simply specify INDEX_NONE as the index to display at.

For DisplayTime, pass in how long to show onscreen, something like 5.f.

For Color, you can simply use the static colors if you wish, such as FColor::Red, FColor::Blue, etc.

For Message, this can be a static string using TEXT(“Message here!”) or you can add dynamic text as we did with UE_LOG. However, it works a little differently, and we will instead need to use Printf if we want dynamic text. This can be done as so:

FString::Printf(TEXT(“I have %d items”), items.Num())

This would make the whole on-screen-debug-message code look like the following:

GEngine->AddOnScreenDebugMessage(INDEX_NONE, 5.f, FColor::Red, FString::Printf(TEXT("%s spawned in an ItemBounds object! Current Overlaps is %d"), *item->nameTag.ToString(), item->itemBoundsOverlaps));

Conclusion

And there you have it! As a quick recap, I’m going to just paste a little “cheat-sheet” that has some quick references for how to log and format!

Formatting:

  • %d - integer

  • %f - float

  • %s - *string (FString)

Verbosities:

  • Fatal

  • Error

  • Warning

  • Display

  • Log

  • Verbose

  • VeryVerbose

UE_LOG

UE_LOG(LogTemp,  Display, TEXT("%s spawned in an ItemBounds object! Current Overlaps is %d"), *item->nameTag.ToString(), item->itemBoundsOverlaps);

On Screen Debug Log (Print String)

GEngine->AddOnScreenDebugMessage(INDEX_NONE, 5.f, FColor::Red, FString::Printf(TEXT("%s spawned in an ItemBounds object! Current Overlaps is %d"), *item->nameTag.ToString(), item->itemBoundsOverlaps));

Custom Log Category

.h file = DECLARE_LOG_CATEGORY_EXTERN(CustomLogCategory, LogVerbosity, CompiledVerbosity); 
.cpp file = DEFINE_LOG_CATEGORY(CustomLogCategory);

If you found this tutorial helpful and want to help support me in creating this content that I host and publish for free, please consider contributing to my Patreon or Ko-fi!