This class can be used to create custom Gameplay Debugger categories. It’s recommended to have these in a separate editor-only module.

Registering a custom category

You can register the category for example in a custom editor module’s StartupModule:

#if WITH_GAMEPLAY_DEBUGGER
	IGameplayDebugger& GameplayDebuggerModule = IGameplayDebugger::Get();
	GameplayDebuggerModule.RegisterCategory(
		"Tapegame",
		IGameplayDebugger::FOnGetCategory::CreateStatic(&FGameplayDebuggerCategory_Tapegame::MakeInstance),
		EGameplayDebuggerCategoryState::EnabledInGameAndSimulate
	);
	GameplayDebuggerModule.NotifyCategoriesChanged();
#endif

You can also unregister the category in ShutdownModule. The name should match the one you registered.

#if WITH_GAMEPLAY_DEBUGGER
	if (IGameplayDebugger::IsAvailable())
	{
		IGameplayDebugger& GameplayDebuggerModule = IGameplayDebugger::Get();
		GameplayDebuggerModule.UnregisterCategory("CategoryName");
		GameplayDebuggerModule.NotifyCategoriesChanged();
	}
#endif

Implementing a custom category

The category needs two functions: CollectData and DrawData. Override them from the base class. They are called automatically, with the call interval determined by CollectDataInterval (by default, called every tick).

The category is expected to have a “replication data pack” - a struct which stores all the debug data this category uses. The implementation example below shows how this is used.

The DrawData function receives a FGameplayDebuggerCanvasContext parameter. This contains a number of functions that can be used to display the data. For example, using Printf will display it in the debugger’s section of the UI. You can also do more complex things, such as overlaying the information on an actor:

//assuming D is a struct which contains a Position FVector
//which is some actor's location in the world
const FVector2D Loc = CanvasContext.ProjectLocation(D.Position);
CanvasContext.PrintfAt(
	Loc.X,
	Loc.Y,
	TEXT("Satisfaction: %d\nTags: %s"),
	D.SatisfactionLevel,
	*FString::Join(D.Tags, TEXT(", "))
);

Category implementation example

#pragma once
 
#if WITH_GAMEPLAY_DEBUGGER
 
#include "CoreMinimal.h"
 
#include "GameplayDebuggerCategory.h"
 
class GAMEJAMREWINDEDITOR_API FGameplayDebuggerCategory_Tapegame : public FGameplayDebuggerCategory
{
public:
	FGameplayDebuggerCategory_Tapegame();
 
	virtual void CollectData(APlayerController* OwnerPC, AActor* DebugActor) override;
	virtual void DrawData(APlayerController* OwnerPC, FGameplayDebuggerCanvasContext& CanvasContext) override;
 
	static TSharedRef<FGameplayDebuggerCategory> MakeInstance();
 
protected:
	struct FRepData
	{
		float AverageRating = 0;
 
		void Serialize(FArchive& Ar);
	};
 
	FRepData DataPack;
};
 
#endif
 
 
#include "GameplayDebuggerCategory_Tapegame.h"
 
#include "Core/TapeGameModeBase.h"
#include "GameFramework/PlayerController.h"
#include "Kismet/GameplayStatics.h"
#include "World/WorldManager.h"
 
#if WITH_GAMEPLAY_DEBUGGER
 
FGameplayDebuggerCategory_Tapegame::FGameplayDebuggerCategory_Tapegame()
{
	CollectDataInterval = 5;
	SetDataPackReplication<FRepData>(&DataPack);
}
 
void FGameplayDebuggerCategory_Tapegame::CollectData(APlayerController* OwnerPC, AActor* DebugActor)
{
	if(!OwnerPC)
	{
		return;
	}
	
	const auto& GameMode = Cast<ATapeGameModeBase>(UGameplayStatics::GetGameMode(OwnerPC));
	if(GameMode)
	{
		DataPack.AverageRating = GameMode->WorldManager->GetAverageCustomerStoreRatingPercentage();
	}
}
 
void FGameplayDebuggerCategory_Tapegame::DrawData(APlayerController* OwnerPC,
                                                  FGameplayDebuggerCanvasContext& CanvasContext)
{
	CanvasContext.Printf(TEXT("{yellow}Average rating: {white}%.2f%%"), DataPack.AverageRating * 100);
}
 
TSharedRef<FGameplayDebuggerCategory> FGameplayDebuggerCategory_Tapegame::MakeInstance()
{
	return MakeShareable(new FGameplayDebuggerCategory_Tapegame());
}
 
void FGameplayDebuggerCategory_Tapegame::FRepData::Serialize(FArchive& Ar)
{
	Ar << AverageRating;
}
 
#endif

Notes

CollectData has a parameter DebugActor. This is the actor which is currently selected in the editor - the user can detach and select another actor, which will become the debug actor.