Printing UObject information

Sometimes to implement a feature in our game we need to know how Unreal Engine works internally, there are a lot of ways to do this: finding any information on the web, reading the engine codes, debugging the program at some point, printing things to the log, and many more.

In this blog post I would like to share some codes that can help us in printing information to the log in order to understand how Unreal Engine works. Without further ado, these are the source codes :

http://pastebin.com/YZex4TRD

There are some debugging functions in the source codes, but the most important one is the TraceObject function.

// Flags for TraceObject
#define TOF_OBJECT_DETAILS     0x01
#define TOF_CLASS_DETAILS      0x02
#define TOF_PROPERTY_DETAILS   0x08

#define TOF_ALL_DETAILS            0xff
#define TOF_NONE               0x00
// End of flags for TraceObject

/**
* Print information of an object to the log.
* @note: This function only works in debug builds. (DebugGame or DebugGameEditor), it does nothing in Development or Shipping build.
* @param    Object                  The object whose information will be written to the log.
* @param    Title                   The title that will be added at the beginning of the information.
* @param    PropertyNameToTrace     List of property names to be included in the the information.
* @param    TraceObjectFlags        Bit flags of what details to be added to the information, the default value is to print all details.
*/
GAME_API void TraceObject( const UObject* Object, const FString& Title = TEXT(""), const TArray<FName>& PropertyNamesToTrace = TArray<FName>(), int32 TraceObjectFlags = TOF_ALL_DETAILS  );

This function is also a part of the game module that I am currently working on ( it’s still far from completio n) that you can get at : https://github.com/fathurahman/game-modules

Usage

Using the TraceObject function is very simple, at the very least you just have to specify the Object that you wish to print and a title that will be written at the beginning of the logs. e.g: `TraceObject( MyObject, TEXT(“Just a test”) ).

If you wish to print information about some properties in the object, you can specify the PropertyNamesToTrace parameter. e.g:

TArray&amp;amp;amp;lt;FName&amp;amp;amp;gt; PropertyNames;
PropertyNames.Add( &amp;amp;amp;quot;Foo&amp;amp;amp;quot; );
PropertyNames.Add( &amp;amp;amp;quot;Bar&amp;amp;amp;quot; );
TraceObject( MyObject, TEXT(&amp;amp;amp;quot;Just another test&amp;amp;amp;quot;), PropertyNames );

There are three categories of information that can be printed by TraceObject function: Object details, Object’s class details, and the last one is property details. By default TraceObject will print all of them but you can control what details should be printed to the log by specifying the TraceObjectFlag.

For example if you do not specify the TraceObjectFlags or you’re using TFO_ALL_DETAILS then it will print out a lot of information. e.g:

LogTrace: OnMatchStateSet [GameState_0] : 
LogTrace:   Object URL    : GameState /Game/Maps/UEDPIE_0_Map_Test.Map_Test:PersistentLevel.GameState_0
LogTrace:   Object Flags  : RF_Transactional RF_Transient 
LogTrace:   Class URL      : Class /Script/Engine.GameState
LogTrace:   Class Flags    : CLASS_Native CLASS_NotPlaceable CLASS_RequiredAPI CLASS_TokenStreamAssembled CLASS_HasInstancedReference CLASS_Intrinsic CLASS_Constructed 
LogTrace:   Class Hierarchy: Object-&amp;amp;amp;gt;Actor-&amp;amp;amp;gt;Info-&amp;amp;amp;gt;GameState
LogTrace:   Property : MatchState
LogTrace:     URL    : NameProperty /Script/Engine.GameState:MatchState
LogTrace:     Flags  : CPF_Edit CPF_BlueprintVisible CPF_BlueprintReadOnly CPF_Net CPF_ZeroConstructor CPF_DisableEditOnTemplate CPF_EditConst CPF_IsPlainOldData CPF_RepNotify CPF_NoDestructor CPF_Protected CPF_HasGetValueTypeHash CPF_NativeAccessSpecifierProtected 
LogTrace:     Value  : EnteringMap
LogTrace:   Property : PreviousMatchState
LogTrace:     URL    : NameProperty /Script/Engine.GameState:PreviousMatchState
LogTrace:     Flags  : CPF_Edit CPF_BlueprintVisible CPF_BlueprintReadOnly CPF_ZeroConstructor CPF_DisableEditOnTemplate CPF_EditConst CPF_IsPlainOldData CPF_NoDestructor CPF_Protected CPF_HasGetValueTypeHash CPF_NativeAccessSpecifierProtected 
LogTrace:     Value  : EnteringMap

But if you specify TFO_PROPERTY_DETAILS | TFO_OBJECT_DETAILS then the class information will not be printed:

LogTrace: OnMatchStateSet [GameState_0] : 
LogTrace:   Object URL    : GameState /Game/Maps/UEDPIE_0_Map_Test.Map_Test:PersistentLevel.GameState_0
LogTrace:   Object Flags  : RF_Transactional RF_Transient 
LogTrace:   Property : MatchState
LogTrace:     URL    : NameProperty /Script/Engine.GameState:MatchState
LogTrace:     Flags  : CPF_Edit CPF_BlueprintVisible CPF_BlueprintReadOnly CPF_Net CPF_ZeroConstructor CPF_DisableEditOnTemplate CPF_EditConst CPF_IsPlainOldData CPF_RepNotify CPF_NoDestructor CPF_Protected CPF_HasGetValueTypeHash CPF_NativeAccessSpecifierProtected 
LogTrace:     Value  : EnteringMap
LogTrace:   Property : PreviousMatchState
LogTrace:     URL    : NameProperty /Script/Engine.GameState:PreviousMatchState
LogTrace:     Flags  : CPF_Edit CPF_BlueprintVisible CPF_BlueprintReadOnly CPF_ZeroConstructor CPF_DisableEditOnTemplate CPF_EditConst CPF_IsPlainOldData CPF_NoDestructor CPF_Protected CPF_HasGetValueTypeHash CPF_NativeAccessSpecifierProtected 
LogTrace:     Value  : EnteringMap

Example Use Case

I have used this function frequently to study how Unreal Engine works, and I must say that it is one of the most useful method for me to learn Unreal Engine.

One of the things that I have done with this function was when I needed to know what objects are instantiated from a certain actor class that I have made, I call the TraceObject function in the class Constructor, PostInitProperties, PostLoad, PostEditImport, Serialize and OnConstruction, I created a blueprint using this class as its parent and spawn the blueprint actor into the editor world and save the map, from the log I learned a lot of useful things, I learned about the existence of a skeleton object inside a blueprint, I learned how Unreal Engine copies the class default object to instanced object, I learned the process of duplicate an actor in the editor, and many more, all just by reading the log while sipping a cup of hot coffee.

One other useful thing that you have probably known is that the log can be quite cluttered with many different things, especially in debug build, thus having a tool to filter the logs will be really useful, I personally use the many different text processing tools provided by Bash (grep, sed, sort, unique, etc.); You can also turn off some log categories that you don’t really care about, but it’s a lot of work and you will most likely missed out some important information by turning off those logs.

Hopefully the function that I have shared in this blog post will be useful for you as it has been for me.

Published by

Fathurahman

I am a game programmer interested in many aspects of game programming especially tools development and User Interface. I am currently using Unreal Engine 5 for both work and off-work projects. I love to do figure drawing and digital painting in my free time.

Leave a comment