前言
在场景有多个NPC在移动时候,我们发现,调试打印起来很麻烦,日志也在动态的刷新,导致观测起来不是很明确,因此,在这给大家分享一个调试的方法,按 ’ 键呼出引擎打印的一些Debug信息,我们可以看到它是一直存在的。
这部分用于对应小键盘按键,按一次显示,再按一次隐藏,比如AI的对应数字键1,它目前是绿色的,代表是显示的
大家也可以参考源码的写,比如:FGameplayDebuggerCategory_EQS
、FGameplayDebuggerCategory_EQS
等。
首先:创建继承自FGameplayDebuggerCategory
通常情况下,我们只需要重写CollectData,DrawData,MakeInstance一个收集数据一个绘制数据,一个获取背了你们实例
,而将FRepData序列化之后作为数据传输,因此,我们还要给它加一个Serialize序列化函数,内部的打印信息根据自己的需求。
里面的ACharacterBase是我用于随意构建的基类,GetDebugInfo用于传输蓝图需要打印的数据
.cs文件添加:
PrivateDependencyModuleNames.AddRange(new string[] { "GameplayDebugger" });
.cpp
#pragma once
#if WITH_GAMEPLAY_DEBUGGER
#include "CoreMinimal.h"
#include "GameplayDebuggerCategory.h"
/**
*
*/
class YOURPROJECTNAME_API FCustomDebugCategory final : public FGameplayDebuggerCategory
{
public:
FCustomDebugCategory();
virtual void CollectData(APlayerController* OwnerPC, AActor* DebugActor) override;
virtual void DrawData(APlayerController* OwnerPC, FGameplayDebuggerCanvasContext& CanvasContext) override;
static TSharedRef<FGameplayDebuggerCategory> MakeInstance();
protected:
struct FRepData
{
//用于打印传出过来的对象名字
FString Name;
//用于打印的字符串数组
TArray<FString> DebugInfo;
//序列化函数
void Serialize(FArchive& Ar);
};
FRepData DataPack;
};
#endif
.h
#include "CustomDebugCategory.h"
#include "CharacterBase.h"
#if WITH_GAMEPLAY_DEBUGGER
FCustomDebugCategory::FCustomDebugCategory()
{
SetDataPackReplication<FRepData>(&DataPack);
}
void FCustomDebugCategory::CollectData(APlayerController* OwnerPC, AActor* DebugActor)
{
DataPack.DebugInfo.Empty();
DataPack.Name = "None";
if (OwnerPC)
{
ACharacterBase* CharacterBase = Cast<ACharacterBase>(DebugActor);
if (!CharacterBase)
{
return;
}
DataPack.Name = GetNameSafe(DebugActor);
DataPack.DebugInfo = CharacterBase->GetDebugInfo();
}
}
void FCustomDebugCategory::DrawData(APlayerController* OwnerPC, FGameplayDebuggerCanvasContext& CanvasContext)
{
constexpr float StartPosX = 10.0f;
CanvasContext.PrintfAt(StartPosX, 100, TEXT("Name : {red}%s"), *DataPack.Name);
FVector2D ViewPortSize;
GEngine->GameViewport->GetViewportSize(ViewPortSize);
int Index = 0;
for (const FString& Data : DataPack.DebugInfo)
{
float PosY = 140 + Index * 20;
if (PosY >= ViewPortSize.Y - 15.f)
{
PosY -= (ViewPortSize.Y - 140);
}
CanvasContext.PrintfAt(StartPosX, PosY, FColor::Green, TEXT("%s"), *Data);
Index++;
}
}
TSharedRef<FGameplayDebuggerCategory> FCustomDebugCategory::MakeInstance()
{
return MakeShareable(new FCustomDebugCategory());
}
void FCustomDebugCategory::FRepData::Serialize(FArchive& Ar)
{
Ar << Name;
Ar << DebugInfo;
}
#endif
module文件里注册Category
// Copyright Epic Games, Inc. All Rights Reserved.
#include "FYourProjectNameModule.h"
#include "Modules/ModuleManager.h"
#if WITH_GAMEPLAY_DEBUGGER
#include "GameplayDebugger.h"
#include "CustomDebugCategory.h"
#endif
void FYourProjectNameModule::StartupModule()
{
#if WITH_GAMEPLAY_DEBUGGER
IGameplayDebugger& GameplayDebuggerModule = IGameplayDebugger::Get();
GameplayDebuggerModule.RegisterCategory("CustomCategory",
IGameplayDebugger::FOnGetCategory::CreateStatic(&FCustomDebugCategory::MakeInstance),
EGameplayDebuggerCategoryState::EnabledInGameAndSimulate, 6);//6代表注册按键6,最后一位6不传的话,代表默认按照顺序注册,第几个就是第几个键
GameplayDebuggerModule.NotifyCategoriesChanged();
#endif // WITH_GAMEPLAY_DEBUGGER
}
void FYourProjectNameModule::ShutdownModule()
{
#if WITH_GAMEPLAY_DEBUGGER
if (IGameplayDebugger::IsAvailable())
{
IGameplayDebugger& GameplayDebuggerModule = IGameplayDebugger::Get();
GameplayDebuggerModule.UnregisterCategory("CustomCategory");
GameplayDebuggerModule.NotifyCategoriesChanged();
}
#endif // W
}
IMPLEMENT_PRIMARY_GAME_MODULE(FYourProjectNameModule, YourProjectName, "YourProjectName");
重载自己传参的函数并传入测试数据
当准心对准想要检测的NPC,按下 ’ 键,并按对应的数字键6,并关掉其他显示的数字键(按一次开,再按一次关),得到结果:
关掉调试信息,也一样,再次按下 ’ 键即可关掉