概要
UnrealEngine の文字列などのデバッグ表示のメモ書きです。
環境
Windows10
Visual Studio 2017
UnrealEngine 4.24, 5.3.2
更新履歴
日付 | 内容 |
---|---|
2020/03/28 | 初版 |
2024/09/02 | ビューポートサイズの取得について追記 |
参考
以下を参考にさせて頂きました、ありがとうございます。
UE4:UEngine::AddOnScreenDebugMessage
第0036回 / デバッグ表示を調査
[UE4] UDebugDrawService による2Dデバッグ描画 (C++)
UE4: 点や線を簡易的に3D空間内へ描画する方法、あるいは UKismetSystemLibrary::DrawDebug 系の紹介
2D表示
スクリーンへの表示です。
2Dデバッグログ文字表示(C++)
画面左上に表示されます。
位置指定ができないので大量に出すと流れます。
以下、C++でのコード例。
FColor _Col = FColor::White;
FVector2D _Scl = FVector2D(3.0f, 3.0f);
GEngine->AddOnScreenDebugMessage(-1, 0.0f, _Col, FString::Printf(TEXT("Test!")), true, _Scl);
2Dデバッグログ文字表示(BP)
BPでは Print String
や Print Text
です。
引数文字の改行は Shift + Enter
です。
Canvasを使った表示(C++)
Canvas を使った2Dデバッグ文字表示で、表示位置を指定できます。
"Engine/Source/Runtime/Engine/Canvas.h"
コード例では、GameInstanceSubsystemを使ってフォント取得、デリゲートの登録/解除を行い、呼ばれる描画メソッドも持っています。
UCLASS()
class TEST_API UMyGameInstanceSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
UMyGameInstanceSubsystem();
public:
// 初期化
virtual void Initialize(FSubsystemCollectionBase& Collection);
// 初期化解除
virtual void Deinitialize();
// 描画
void Draw(UCanvas* InCanvas, APlayerController* InPC);
private:
// 登録デリゲート
FDelegateHandle DrawDebugDelegate;
// フォント
UPROPERTY(Transient)
class UFont* FontObject;
};
#include "MyGameInstanceSubsystem.h"
#include "Engine.h"
UMyGameInstanceSubsystem::UMyGameInstanceSubsystem()
{
// フォント用意
static ConstructorHelpers::FObjectFinder<UFont> font(TEXT("/Engine/EngineFonts/Roboto"));
FontObject = font.Object;
}
// 初期化
void UMyGameInstanceSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
// デリゲートを登録
auto drawDebugDelegate = FDebugDrawDelegate::CreateUObject(this, &UMyGameInstanceSubsystem::Draw);
if( drawDebugDelegate.IsBound() ){
this->DrawDebugDelegate = UDebugDrawService::Register(TEXT("GameplayDebug"), drawDebugDelegate);
}
}
// 初期化解除
void UMyGameInstanceSubsystem::Deinitialize()
{
// デリゲート登録解除
if( this->DrawDebugDelegate.IsValid() ){
UDebugDrawService::Unregister(this->DrawDebugDelegate);
this->DrawDebugDelegate.Reset();
}
}
// 描画
void UMyGameInstanceSubsystem::Draw(UCanvas* InCanvas, APlayerController* InPC)
{
if (!InCanvas || !InCanvas->Canvas){
return;
}
// 文字描画1(DrawItemでの表示)
FString _DispString;
FVector2D _Pos = FVector2D(320.0f, 100.0f);
FVector2D _Scl = FVector2D(3.0f, 3.0f);
FLinearColor _Col = FLinearColor::Yellow;
_DispString = FString::Printf(TEXT("test"));
FCanvasTextItem _TextItem(_Pos, FText::FromString(_DispString), this->FontObject, _Col);
_TextItem.Scale = _Scl;
InCanvas->DrawItem(_TextItem);
// 文字描画2(DrawTextでの表示)
FVector2D _Pos2 = FVector2D(320.0f, 130.0f);
FString _DispString2 = FString::Printf(TEXT("test2"));
InCanvas->K2_DrawText(this->FontObject, _DispString2, _Pos2, _Scl, FLinearColor::Red);
}
実行すると画面中央付近に黄色文字と赤文字でテスト文字が3倍スケールで表示されます。
ビューポートサイズの取得について
ビューポートサイズの取得は GEngine->GameViewport->GetViewportSize
で取得ができますが、Windowsのディスプレイ設定で拡大などしていた場合、そのままでは位置がズレてしまいます。
そのためDPIスケールを取得してビューポートサイズを再計算してあげる必要があります、以下コード例。
// ビューポートのサイズを取得
FVector2D _ViewportSize;
GEngine->GameViewport->GetViewportSize(_ViewportSize);
// DPIスケールを取得
const float _DPIScale = GEngine->GameViewport->GetDPIScale();
// DPIスケールを考慮したビューポートサイズを計算
FVector2D _ScaledViewportSize = _ViewportSize / _DPIScale;
他に以下のように FPlatformApplicationMisc
を使って拡大率を取得する方法もあるようです。
#include "HAL/PlatformApplicationMisc.h"
#include "Misc/Optional.h"
void GetCurrentDPIScale()
{
// ウィンドウの中心座標を取得(例として(0, 0))
int32 _ScreenX = 0;
int32 _ScreenY = 0;
// DPI スケールを取得
float _DPIScale = FPlatformApplicationMisc::GetDPIScaleFactorAtPoint(_ScreenX, _ScreenY);
}
FPlatformApplicationMisc
を使うには Build.cs に "ApplicationCore" を追加する必要があることに注意。
3D表示
3D世界への表示です。
アクターなどの任意のオブジェクトの情報を出す場合に使うと思います。
Kismetライブラリでの表示
アクター位置など3D世界への文字表示ができます。
ソースは
"Engine/Source/Runtime/Engine/Class/Kismet/KismetSystemLibrary.h"
です。
以下コード例。
#include "Kismet/KismetSystemLibrary.h"
// アクター位置への表示
UKismetSystemLibrary::DrawDebugString(GetWorld(), GetActorLocation(), FString::Printf(TEXT("MyActor")), nullptr, FLinearColor::Black, 0);
文字以外にもラインやスフィアなどいろいろあります。
// ライン
UFUNCTION(BlueprintCallable, Category="Rendering|Debug", meta=(WorldContext="WorldContextObject", DevelopmentOnly))
static void DrawDebugLine(UObject* WorldContextObject, const FVector LineStart, const FVector LineEnd, FLinearColor LineColor, float Duration=0.f, float Thickness = 0.f);
// スフィア
UFUNCTION(BlueprintCallable, Category="Rendering|Debug", meta=(WorldContext="WorldContextObject", DevelopmentOnly))
static void DrawDebugSphere(UObject* WorldContextObject, const FVector Center, float Radius=100.f, int32 Segments=12, FLinearColor LineColor = FLinearColor::White, float Duration=0.f, float Thickness = 0.f);
// アロー
UFUNCTION(BlueprintCallable, Category="Rendering|Debug", meta=(WorldContext="WorldContextObject", DevelopmentOnly))
static void DrawDebugArrow(UObject* WorldContextObject, const FVector LineStart, const FVector LineEnd, float ArrowSize, FLinearColor LineColor, float Duration=0.f, float Thickness = 0.f);
BPだと DrawDebugString
で3D世界へ文字表示ができます。
DrawDebugHelpers での表示
Kismetライブラリと同様に3D世界への表示に使えます。
ソースは
"Engine/Source/Runtime/Engine/Public/DrawDebugHelpers.h"
です。
// 文字
void DrawDebugString(const UWorld* InWorld, FVector const& TextLocation, const FString& Text, class AActor* TestBaseActor = NULL, FColor const& TextColor = FColor::White, float Duration = -1.000000, bool bDrawShadow = false, float FontScale = 1.f);
// ライン
void DrawDebugLine(const UWorld* InWorld, FVector const& LineStart, FVector const& LineEnd, FColor const& Color, bool bPersistentLines = false, float LifeTime=-1.f, uint8 DepthPriority = 0, float Thickness = 0.f);
// ボックス
void DrawDebugBox(const UWorld* InWorld, FVector const& Center, FVector const& Extent, FColor const& Color, bool bPersistentLines = false, float LifeTime=-1.f, uint8 DepthPriority = 0, float Thickness = 0.f);
まとめ
UMG以外のデバッグ表示をまとめました。
スクリーン座標への2Dデバッグ文字表示の実装がやや面倒です。