[UE4] HUDでデバッグ表示をカスタマイズする

![dabf63d909454cf7494e93a83caef720.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/dd934586-5865-9c31-9b8c-530afe3eeb64.png)
PrintString や AddOnScreenDebugMessage をお使いのあなた！
左上固定ではなく自由なレイアウトでデバッグ表示をしてみませんか！
# HUD の現在
UE5 になっても AHUD は死んでませんでした。このクラスどうやって使うの？使ってる人いるの？
[猫でも分かるUMG](https://www.slideshare.net/EpicGamesJapan/umg-80334310)でも"デバッグ用として使用されることが多い"と書かれてますね！
じゃあどうやってデバッグ用クラスにするとよいのか、そんな感じで触れていきたいと思います。
## UDebugDrawService クラス
デバッグ表示のヘルパークラス、そして今回の主役です。
まぁ HUD とか関係なくデバッグ表示処理を書きたいクラスに直接実装してもいいんです。
## デバッグ HUD の実装
※実例は AAbilitySystemDebugHUD を参考に作成しています

```C++:ADebugHUD.h
#pragma once

#include "GameFramework/HUD.h"

//
#include "Debug/DebugDrawService.h"

#if WITH_GAMEPLAY_DEBUGGER
#include "GameplayDebuggerTypes.h"
#endif

#include "DebugHUD.generated.h"

UCLASS()
class ADebugHUD : public AHUD
{
	GENERATED_BODY()

public:
	static void ToggleDebugHUD( UWorld* InWorld, UClass* DebugHUDClass, FDelegateHandle& DrawDebugDelegateHandle );

public:
	void DrawDebugHUD( UCanvas* Canvas, APlayerController* );
};

```

```C++:ADebugHUD.cpp
#include "DebugHUD.h"

// Debug表示の実装
void ADebugHUD::DrawDebugHUD( UCanvas* InCanvas, APlayerController* )
{
	// 引数APlayerController*は必ずNullになるので注意
	// 呼び出し元のUDebugDrawService::Drawを参照
	Canvas = InCanvas;
	if ( !Canvas )
	{
		return;
	}

	if ( APlayerController* PC = GetWorld()->GetFirstPlayerController() )
	{
		// World内のMyCharacterクラスを取得
		// ※毎フレ走るには重い処理になりうるので、代替手段を考慮すること
		TArray<AActor*> FoundActors;
		UGameplayStatics::GetAllActorsOfClass( this, AMyCharacter::StaticClass(), FoundActors );

		for ( AActor* FoundActor : FoundActors )
		{
			auto* TargetCharacter = CastChecked<AMyCharacter>( FoundActor );
#if WITH_GAMEPLAY_DEBUGGER
			// Actor.WorldLocationからスクリーン座標に変換
			FVector2D ScreenPosition;
			if ( UGameplayStatics::ProjectWorldToScreen( PC, TargetCharacter->GetActorLocation(), ScreenPosition, false ) )
			{
				FGameplayDebuggerCanvasContext CanvasContext( Canvas, GEngine->GetSmallFont() );
				CanvasContext.FontRenderInfo.bEnableShadow = true;
				CanvasContext.CursorX = CanvasContext.DefaultX = ScreenPosition.X;
				CanvasContext.CursorY = CanvasContext.DefaultY = ScreenPosition.Y;

				// 表示したい情報を追加する
				CanvasContext.Printf( FColor::Magenta, TEXT( "%s" ), *TargetCharacter->GetName() );
				CanvasContext.Printf( FColor::Magenta, TEXT( " {cyan}Health: {white}%d" ), (int32) TargetCharacter->GetHealth() );
			}
#endif
		}
	}
}

#if !UE_BUILD_SHIPPING

// HUDの生成/破棄
void ADebugHUD::ToggleDebugHUD( UWorld* InWorld, UClass* DebugHUDClass, FDelegateHandle& DrawDebugDelegateHandle )
{
	if ( !InWorld )
	{
		return;
	}

	ADebugHUD* HUD = nullptr;

	// World内単一のDebugHUDクラスを探す
	for ( TActorIterator<ADebugHUD> It( InWorld ); It; ++It )
	{
		if ( *It && It->IsA( DebugHUDClass ) )
		{
			HUD = *It;
			break;
		}
	}

	// HUD アクターの生成/削除 & デリゲートのバインド
	if ( !HUD )
	{
		HUD = InWorld->SpawnActor<ADebugHUD>( DebugHUDClass );
		DrawDebugDelegateHandle = UDebugDrawService::Register(
			TEXT( "MyDebug" ), FDebugDrawDelegate::CreateUObject( HUD, &ThisClass::DrawDebugHUD ) );
	}
	else
	{
		UDebugDrawService::Unregister( DrawDebugDelegateHandle );
		HUD->Destroy();
	}
}

static void ToggleDebugHUD( const TArray<FString>& Args, UWorld* InWorld )
{
	static FDelegateHandle DrawDebugDelegateHandle;
	ADebugHUD::ToggleDebugHUD( InWorld, ADebugHUD::StaticClass(), DrawDebugDelegateHandle );
}

// コンソールコマンドに登録する
FAutoConsoleCommandWithWorldAndArgs DebugHUDToggleCommand( TEXT( "Debug.ToggleHUD" ),
	TEXT( "toggle debug HUD drawing." ), FConsoleCommandWithWorldAndArgsDelegate::CreateStatic( ToggleDebugHUD ) );

#endif	  // !UE_BUILD_SHIPPING
```

FGameplayDebuggerCanvasContext がキャンバスの描画クラスで、内部で改行位置の計算とかもやってくれてます。
{色タグ} などを途中に挟むことで文字色も変更可能。お手軽ですねえ。

```C#:YourProject.Build.cs
if (Target.bBuildDeveloperTools || Target.Configuration != UnrealTargetConfiguration.Shipping)
{
	PublicDependencyModuleNames.Add("GameplayDebugger");
}
```

GameplayDebug モジュールの追加が必要です。お忘れなく。
## コンソールコマンドの実行
![8518af194b549638c6cdab40f8f5e2a8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/edb4c1a0-cb4c-df9c-34c8-0297e82d8c8e.png)
@キーを押して"Debug.ToggleHUD"を実行

# 使用例
+ キャラクターパラメータ表示
+ エネミーのヘイトリスト
+ Spawner、CheckPoint、WorldActorの詳細表示 などなど