Logging can be quite cumbersome to type every time, like:
UE_LOG(LogTemp, Warning, TEXT("Your message"));
It is easier to remember and faster to type like this:
GAME_LOG("Your message");
GAME_WARN("Your warning");
GAME_ERROR("Your error");
GAME_SCREENLOG("Your screen message");
To setup something like that, here’s how I’ve done it:
First, open the project main .h file (like BattleTank.h) and add this:
#if UE_BUILD_DEVELOPMENT
#define GAME_LOG_DEFINED 1
DECLARE_LOG_CATEGORY_EXTERN(GameLog, Log, All);
#define NETMODE_WORLD (((GEngine == nullptr) || (GetWorld() == nullptr)) ? TEXT("") \
: (GEngine->GetNetMode(GetWorld()) == NM_Client) ? TEXT("[Client]") \
: (GEngine->GetNetMode(GetWorld()) == NM_ListenServer) ? TEXT("[ListenServer]") \
: (GEngine->GetNetMode(GetWorld()) == NM_DedicatedServer) ? TEXT("[DedicatedServer]") \
: TEXT("[Standalone]"))
#if _MSC_VER
#define FUNC_NAME TEXT(__FUNCTION__)
#else // FIXME - GCC?
#define FUNC_NAME TEXT(__func__)
#endif
#define GAME_LOG(Message, ...) \
{ \
const FString Msg = FString::Printf(TEXT(Message), ##__VA_ARGS__); \
UE_LOG(GameLog, Log, TEXT("::::::: %s %s : %s :::::::"), NETMODE_WORLD, FUNC_NAME, *Msg); \
}
#define GAME_SCREENLOG(Message, ...) \
{ \
const FString Msg = FString::Printf(TEXT(Message), ##__VA_ARGS__); \
GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::White, Msg); \
}
#define GAME_WARN(Message, ...) \
{ \
const FString Msg = FString::Printf(TEXT(Message), ##__VA_ARGS__); \
UE_LOG(GameLog, Warning, TEXT("::::::: %s %s : %s :::::::"), NETMODE_WORLD, FUNC_NAME, *Msg); \
GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Yellow, Msg); \
}
#define GAME_ERROR(Message, ...) \
{ \
const FString Msg = FString::Printf(TEXT(Message), ##__VA_ARGS__); \
UE_LOG(GameLog, Error, TEXT("::::::: %s %s : %s :::::::"), NETMODE_WORLD, FUNC_NAME, *Msg); \
GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, Msg); \
}
#define GAME_HALT(Message, ...) \
{ \
const FString Msg = FString::Printf(TEXT(Message), ##__VA_ARGS__); \
UE_LOG(GameLog, Fatal, TEXT("====== %s %s : %s ======"), NETMODE_WORLD, FUNC_NAME, *Msg); \
}
#else
#define GAME_LOG(Message, ...)
#define GAME_SCREENLOG(Message, ...)
#define GAME_WARN(Message, ...)
#define GAME_ERROR(Message, ...)
#define GAME_HALT(Message, ...)
#endif
Now, open the .cpp file (BattleTank.cpp) and write:
#if GAME_LOG_DEFINED
DEFINE_LOG_CATEGORY(GameLog);
#endif
And that’s it!
I made the warn and the error logs to also print to the screen to make sure I don’t miss them since they are important.
Another advantage to this setup is that the file and the line number from where the log is coming will also be printing, along side with the current netmode.
Having your own log category will make it easier to spot your message and you can filter for them by typing GameLog in the search field.
I wanted to have a custom color for the logs, but the documented way of doing that doesn’t work anymore unfortunately. So, I’ve added a bunch of “:::::” to the message to make it easier to find them along the engine own logs.
All this was possible by reading these tutorials:
https://wiki.unrealengine.com/Logs,_Printing_Messages_To_Yourself_During_Runtime
https://wiki.unrealengine.com/Log_Macro_with_Netmode_and_Colour
