Skip to content

Creating Custom Gameplay Debugger Categories

In this post we’re going to see how to create a custom gameplay debugger category. By the time of this writing the official documentation page is outdated.

This post was written in 4.15 version of the engine. Depending on the time you’re reading this, this information may be outdated as well.

Please note that this is a followup post to my “Creating Custom Modules” post. So before going any further, make sure that you have followed that post and everything works fine.

Modifying the .Build.cs file

Before we go any further, open up the .Build.cs file of your module (in my case this will be OrfeasModule.Build.cs file and add the following lines of code:

 if (UEBuildConfiguration.bBuildDeveloperTools || (Target.Configuration != UnrealTargetConfiguration.Shipping && Target.Configuration != UnrealTargetConfiguration.Test))
        {
            PrivateDependencyModuleNames.Add("GameplayDebugger");
            Definitions.Add("WITH_GAMEPLAY_DEBUGGER=1");
        }
        else
        {
            Definitions.Add("WITH_GAMEPLAY_DEBUGGER=0");
        }

When you’re done with that, add a new C+ class that inherits the UObject inside your module and name it CustomGameplayDebugger so you can follow the tutorial easier.

Creating the GameplayDebuggerCategory

Open up the header file of the CustomGameplayDebugger class and erase the code that the editor has written for you and declare the following class:

#pragma once

#include "CoreMinimal.h"

#if WITH_GAMEPLAY_DEBUGGER

#include "GameplayDebuggerCategory.h"

//Forward declarations
class AActor;
class APlayerController;
class FGameplayDebuggerCanvasContext;

//The data we're going to print inside the viewport
struct FDataToPrint
{
	float HP;
	float Damage;
};

//The class of our custom gameplay debugger category
class FGameplayDebuggerCategory_Orfeas : public FGameplayDebuggerCategory
{

protected:
	
	//The data that we're going to print
	FDataToPrint Data;

public:

	FGameplayDebuggerCategory_Orfeas();

	/** Creates an instance of this category - will be used on module startup to include our category in the Editor */
	static TSharedRef<FGameplayDebuggerCategory> MakeInstance();

	/** Collects the data we would like to print */
	virtual void CollectData(APlayerController* OwnerPC, AActor* DebugActor) override;

	/** Displays the data we collected in the CollectData function */
	virtual void DrawData(APlayerController* OwnerPC, FGameplayDebuggerCanvasContext& CanvasContext) override;
};

#endif

Then, open up the source file of your class and type in the following code:

#include "GDBlogPostCharacter.h"

#if WITH_GAMEPLAY_DEBUGGER

#include "DebugRenderSceneProxy.h"

FGameplayDebuggerCategory_Orfeas::FGameplayDebuggerCategory_Orfeas()
{
	bShowOnlyWithDebugActor = false;
}

TSharedRef<FGameplayDebuggerCategory> FGameplayDebuggerCategory_Orfeas::MakeInstance()
{
	return MakeShareable(new FGameplayDebuggerCategory_Orfeas());
}

void FGameplayDebuggerCategory_Orfeas::CollectData(APlayerController* OwnerPC, AActor* DebugActor)
{

	if (DebugActor)
	{
		AGDBlogPostCharacter* Char = Cast<AGDBlogPostCharacter>(DebugActor);

		if (Char)
		{
			//Store the data to our struct
			Data.HP = Char->Health;
			Data.Damage = Char->MaxDamage;
		}
	}
}

void FGameplayDebuggerCategory_Orfeas::DrawData(APlayerController* OwnerPC, FGameplayDebuggerCanvasContext& CanvasContext)
{
	//Test print with white text
	CanvasContext.Printf(TEXT("Test Print"));

	CanvasContext.Printf(FColor::Yellow, TEXT("Yet again another print!"));

	//Print the health data with green color
	CanvasContext.Printf(TEXT("{green}HP: %s"), *FString::SanitizeFloat(Data.HP));

	//Print the damage data with red color
	CanvasContext.Printf(TEXT("{red}Damage: %s"), *FString::SanitizeFloat(Data.Damage));
}

#endif

Before you attempt to build your project, make sure that your character class is marked with the appropriate *_API macro – otherwise you will encounter a linker error. (Special thanks to Mieszko Zielinski for his help on this one).

In my case, my project is named “GDBlogPost” so my character class is going to have the following macro in the class declaration:

class GDBLOGPOST_API AGDBlogPostCharacter : public ACharacter

Moreover, don’t forget to add the Health and MaxDamage properties of the character somewhere in its header file:

public:

	UPROPERTY(EditAnywhere)
	float Health;

	UPROPERTY(EditAnywhere)
	float MaxDamage;

The last things we need to do, is to tell our Module to register our custom gameplay debugger category on its startup. Moreover, we need to tell our Module to unregister our category if its shutdown. To do that navigate to your module’s source file and type in the following code:

void FOrfeasModule::StartupModule()
{
	UE_LOG(OrfeasModule, Warning, TEXT("Orfeas module has started!"));

#if WITH_GAMEPLAY_DEBUGGER

	//If the gameplay debugger is available, register the category and notify the editor about the changes
	IGameplayDebugger& GameplayDebuggerModule = IGameplayDebugger::Get();

	GameplayDebuggerModule.RegisterCategory("OrfeasCustomCategory", IGameplayDebugger::FOnGetCategory::CreateStatic(&FGameplayDebuggerCategory_Orfeas::MakeInstance), EGameplayDebuggerCategoryState::EnabledInGameAndSimulate);

	GameplayDebuggerModule.NotifyCategoriesChanged();

#endif
}

void FOrfeasModule::ShutdownModule()
{
	UE_LOG(OrfeasModule, Warning, TEXT("Orfeas module has shut down"));

#if WITH_GAMEPLAY_DEBUGGER
	//If the gameplay debugger is available, unregister the category
	if (IGameplayDebugger::IsAvailable())
	{
		IGameplayDebugger& GameplayDebuggerModule = IGameplayDebugger::Get();
		GameplayDebuggerModule.UnregisterCategory("OrfeasCustomCategory");
	}
#endif
}

Once you’re done with that, save and build your project. At this point, if you navigate to your Project’s settings inside the Gameplay Debugger option, you will have the following category available:

(Click on image to enlarge in a new tab)

You may have to restart your Editor if that option isn’t visible.

Enabling the Gameplay Debugger

To enable the gameplay debugger click on the apostrophe key on your keyboard (‘) and type in the “showflag.debugAI 1” console command while simulating your game.

Then, select your character. The following window will appear:

(Click on image to enlarge in a new tab)
Avatar photo

Comments (7)

    1. Hey Tom,

      I was following the engine’s source code when I came up with this. According to this comment, in order to register a category in general, a module is required (not a custom one though).

      Thanks for your kind words!

      -Orfeas

  1. Hi, I apologize if this is not totally on topic but I don’t know where else to ask… u_u

    I was wondering, would it be possible to create a .h and .cpp file entirely in Visual Studio that contains only a collection of UFUNCTION() that can be accessed from every blueprint you make inside the blueprint editor?
    Kind of like the basic nodes (for example “float*float”) that are shared across all BP

    If yes, could you kindly point me in the direction of the appropriate tutorial or example? ^_^

    1. Hello Marcus,

      What you’re looking for is called “Blueprint Function Library”. You have to add via the C++ wizard though.

      -Orfeas

      1. I actually bumped into it yesterday by pure luck by digging on the wiki, but thank you a lot nonetheless for helping me 🙂

  2. Still working on 4.19?
    Experiencing either a bunch of linker errors following this or anything else to try and get this friggen gameplay debugger stuff going lol

  3. Updated build.cs code for latest versions:

    if (Target.bBuildDeveloperTools || (Target.Configuration != UnrealTargetConfiguration.Shipping && Target.Configuration != UnrealTargetConfiguration.Test))
    {
    PrivateDependencyModuleNames.Add(“GameplayDebugger”);
    PublicDefinitions.Add(“WITH_GAMEPLAY_DEBUGGER=1”);
    }
    else
    {
    PublicDefinitions.Add(“WITH_GAMEPLAY_DEBUGGER=0”);
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back To Top