Crear categorías de log para nuestros sistemas en Unreal Engine

Crear categorías de log para nuestros sistemas en Unreal Engine

En muchos libros y tutoriales sobre C++ en Unreal Engine se pueden ver ejemplos dónde se usa UE_LOG para mostrar mensajes que nos ayudan a depurar nuestro código y detectar problemas:

UE_LOG(LogTemp, Warning, TEXT("Hello, I'm here"));
💡
La macro UE_LOG no es la única manera de mostrar mensajes. En Unreal Engine 5.2 se añadió UE_LOGFMT, que ofrece una interfaz más cómoda. Y también esta AddOnScreenDebugMessages()

Imprimir mensajes de con UE_LOG en la categoría LogTemp es una buena opción durante la depuración de problemas.

Sin embargo, podemos querer dejar de forma permanente algunos de estos mensajes para que se emitan en condiciones que podrían ser problemáticas. En ese caso, usar LogTemp como categoría de los mensajes no es buena idea, porque se hace complicado determinar en qué sistema o componente está el problema. En su lugar, es preferible que definamos nuestras propias categorías, de forma que así sea más sencillo localizar los mensajes de un componente e identificar rápidamente el origen del problema.

En Unreal Engine, para definir una categoría de log necesitamos un archivo .h donde declaramos las nuevas categorías y un archivo .cpp donde las definimos. Por ejemplo: LogCategories.h y LogCtegories.cpp.

En la declaración de las nuevas categorías en el archivo .h usamos la macro DECLARE_LOG_CATEGORY_EXTERN así:

// LogCategories.h

DECLARE_LOG_CATEGORY_EXTERN(LogInventorySystem, Log, All);
DECLARE_LOG_CATEGORY_EXTERN(LogMyAnimSystem, Log, All);
//...

De tal forma que:

  • LogInventorySystem es el nombre de la nueva categoría de logs.

  • Log indica el nivel de verbosidad utilizado por defecto. Será el nivel usado si no se indica ninguno a usar UE_LOG. Los valores admitidos son: Fatal, Error, Warning, Display, Log, Verbose y VeryVerbose.

  • El tercer argumento indica el nivel de verbosidad más alto que será incluido al compilar el proyecto. Sí, por ejemplo, se indica All, se incluyen todos los niveles, pero si se indica Warning, no es posible ver mensajes en los niveles de verbosidad Display, Log, Verbose o VeryVerbose. Por tanto, este argumento ofrece una forma sencilla de suprimir todos los mensajes a partir de cierto nivel de verbosidad en la categoría indicada.

Luego, en la definición en el archivo .cpp usamos la macro DEFINE_LOG_CATEGORY indicando solo el nombre de la nueva categoría:

// LogCategories.cpp

DEFINE_CATEGORY_EXTERN(LogInventorySystem);
DEFINE_CATEGORY_EXTERN(LogMyAnimSystem);
//...

Finalmente, podemos incluir LogCategories.h en aquellos archivos donde queramos usar una de estas categorías y utilizarla con UE_LOG con normalidad:

#include "LogCategories.h"

UE_LOG(LogInventorySystem, Warning, TEXT("Inventory component not found"));
UE_LOG(LogInventorySystem, Log, TEXT("%d items added"), NumOfItems);

O con la nueva macro UE_LOGFMT:

#include "LogCategories.h"

UE_LOGFMT(LogInventorySystem, Warning, "Inventory component not found: {0}", GetName());
UE_LOGFMT(LogInventorySystem, Log, "{Count} items added: {OwnerName}",
    ("Count", NumOfItems), ("OwnerName", GetOwner()->GetName()));

Referencias adicionales