[UE] Log 출력하기, Draw Debug 구현

언리얼 엔진에서 Draw Debug는 개발자들이 런타임 동안 다른 게임 시스템이나 코드 로직의 동작을 시각화할 수 있는 기능이다. 게임 엔진에서 일어나는 일을 시각적으로 보여줌으로써 진단하기 어려운 문제나 오류를 식별하는 데 도움이 될 수 있다.
목차
Log 출력하기
CLog 수정
CLog.h
#pragma once #include "CoreMinimal.h" //매크로로 치환 #define LogLine() { CLog::Log(__FILE__, __FUNCTION__, __LINE__);} #define PrintLine() { CLog::Print(__FILE__, __FUNCTION__, __LINE__);} class U2212_03_API CLog { public: static void Log(int32 InValue); static void Log(float InValue); static void Log(const FString& InValue); static void Log(const FVector& InValue); static void Log(const FRotator& InValue); static void Log(const UObject* InValue); static void Log(const FString& InFileName, const FString& InFuncName, int32 InLineNumber); //파일이름, 함수명, 줄번호 // InKey -1을 Default Value로 설정. InDuration(출력시간). FColor(출력색) static void Print(int32 InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue); static void Print(float InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue); static void Print(const FString& InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue); static void Print(const FVector& InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue); static void Print(const FRotator& InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue); static void Print(const UObject* InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue); static void Print(const FString& InFileName, const FString& InFuncName, int32 InLineNumber); };
- 매크로 사용
- #define LogLine() { CLog::Log(__FILE__, __FUNCTION__, __LINE__);}
- #define PrintLine() { CLog::Print(__FILE__, __FUNCTION__, __LINE__);}
CLog.cpp
#include "Utilities/CLog.h" #include "Engine.h" DEFINE_LOG_CATEGORY_STATIC(GP, Display, All) void CLog::Log(int32 InValue) { //GLog->Log("GP", ELogVerbosity::Display, FString::FromInt(InValue)); UE_LOG(GP, Display, L"%d", InValue); } void CLog::Log(float InValue) { UE_LOG(GP, Display, L"%f", InValue); } void CLog::Log(const FString & InValue) { UE_LOG(GP, Display, L"%s", *InValue); } void CLog::Log(const FVector & InValue) { UE_LOG(GP, Display, L"%s", *InValue.ToString()); } void CLog::Log(const FRotator & InValue) { UE_LOG(GP, Display, L"%s", *InValue.ToString()); } void CLog::Log(const UObject * InValue) { FString str; if (!!InValue) str.Append(InValue->GetName()); str.Append(!!InValue ? " Not Null" : "Null"); UE_LOG(GP, Display, L"%s", *str); } void CLog::Log(const FString& InFileName, const FString& InFuncName, int32 InLineNumber) { //예시 //C:\\Test\\Test.cpp int32 index = 0, length = 0; //지역변수는 초기화를 해주는게 좋다. InFileName.FindLastChar(L'\\', index);//반대부터 찾는다. 검색은 오른쪽에서하고 index는 왼쪽에서부터 리턴한다. length = InFileName.Len() - 1; //Index로 다루기 때문에 -1 FString fileName = InFileName.Right(length - index); //예시의 경우 남는부분은 Text.cpp 부분 UE_LOG(GP, Display, L"%s, %s, %d", *fileName, *InFuncName, InLineNumber); } void CLog::Print(int32 InValue, int32 InKey, float InDuration, FColor InColor) { GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, FString::FromInt(InValue)); } void CLog::Print(float InValue, int32 InKey, float InDuration, FColor InColor) { GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, FString::SanitizeFloat(InValue)); } void CLog::Print(const FString & InValue, int32 InKey, float InDuration, FColor InColor) { GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, InValue); } void CLog::Print(const FVector & InValue, int32 InKey, float InDuration, FColor InColor) { GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, InValue.ToString()); } void CLog::Print(const FRotator & InValue, int32 InKey, float InDuration, FColor InColor) { GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, InValue.ToString()); } void CLog::Print(const UObject * InValue, int32 InKey, float InDuration, FColor InColor) { FString str; if (!!InValue) str.Append(InValue->GetName()); str.Append(!!InValue ? " Not Null" : "Null"); GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, str); } void CLog::Print(const FString& InFileName, const FString& InFuncName, int32 InLineNumber) { int32 index = 0, length = 0; InFileName.FindLastChar(L'\\', index); length = InFileName.Len() - 1; FString fileName = InFileName.Right(length - index); FString str = FString::Printf(L"%s, %s, %d", *fileName, *InFuncName, InLineNumber); GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Blue, str); }
- Engine.h는 굉장히 큰 파일이다. 여기서는 추가했지만 Global.h에 넣는것은 지양해야 한다. 속도가 느려진다.
- 언리얼은 전부다 미리 컴파일된 헤더로 취급된다.
- SanitizeFloat()은 float를 문자열로 바꾸어준다.
void AddOnScreenDebugMessage ( uint64 Key, float TimeToDisplay, FColor DisplayColor, const FString & DebugMessage, bool bNewerOnTop, //계속 새로운게 위로 올라갈 것인가? const FVector2D & TextScale //텍스트 크기 )
- AddOnScreenDebugMessage()는 GEngine라는 전역객체에 있는 내장함수.
출력로그

C01_Log & BP_C01_Log
C01_Log.h
#pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "C01_Log.generated.h" UCLASS() class U2212_03_API AC01_Log : public AActor { GENERATED_BODY() public: AC01_Log(); protected: virtual void BeginPlay() override; public: virtual void Tick(float DeltaTime) override; private: float TotalTime; };
C01_Log.cpp
#include "02_Profiler/C01_Log.h" #include "Global.h" AC01_Log::AC01_Log() { PrimaryActorTick.bCanEverTick = true; } void AC01_Log::BeginPlay() { Super::BeginPlay(); CLog::Log(10); CLog::Log(PI); CLog::Log("C01_Log"); CLog::Log(GetActorLocation()); CLog::Log(GetActorRotation()); CLog::Log(this); CLog::Log(__FILE__); CLog::Log(__FUNCTION__); CLog::Log(__LINE__); CLog::Log(__FILE__, __FUNCTION__, __LINE__); LogLine(); CLog::Print(10); CLog::Print(PI); CLog::Print("C01_Log"); CLog::Print(GetActorLocation()); CLog::Print(GetActorRotation()); CLog::Print(this); PrintLine(); } void AC01_Log::Tick(float DeltaTime) { Super::Tick(DeltaTime); TotalTime += DeltaTime; CLog::Print(TotalTime, 100); //Print(InValue, InKey); InKey값은 0보다 큰 값 사용. }
실행화면

Draw Debug
언리얼 엔진에서 Draw Debug는 개발자들이 런타임 동안 다른 게임 시스템이나 코드 로직의 동작을 시각화할 수 있는 기능이다. 게임 엔진에서 일어나는 일을 시각적으로 보여줌으로써 진단하기 어려운 문제나 오류를 식별하는 데 도움이 될 수 있다.
Draw Debug는 게임 세계에서 모양, 선, 텍스트를 그리는 데 사용할 수 있는 몇 가지 기능을 제공한다. 이러한 모양은 플레이어 캐릭터, 적, 발사체와 같은 다른 게임 객체를 표현하는 데 사용될 수 있으며, 선은 이동 경로를 보여주거나 충돌을 추적하는 데 사용될 수 있다.
예를 들어, 개발자가 물리적 충돌 문제를 디버깅하고자 할 경우, 그리기 디버그를 사용하여 관련된 객체의 충돌 모양을 시각화할 수 있다. 이렇게 하면 모양 또는 위치와 관련된 문제를 식별하고 문제를 디버깅하는 데 도움이 된다.
Draw Debug 기능은 언리얼 편집기에서 사용하거나 사용하지 않도록 설정할 수 있으며, 다양한 모양과 선에 대해 다양한 색상과 스타일을 표시하도록 사용자 지정할 수 있습니다. 개발자는 또한 디버그 모양과 라인이 표시되는 기간을 제어할 수 있으며, 문서화 목적으로 스크린샷이나 비디오를 캡처하는 데 사용할 수 있다.
전반적으로 Draw Debug는 언리얼 엔진에서 게임 로직과 동작을 디버깅하는 강력한 도구이며, 개발 중 문제를 진단하는 데 많은 시간과 노력을 절약할 수 있다.
Global.h에 "DrawDebugHelpers.h"추가
Global.h
#pragma once #include "DrawDebugHelpers.h" #include "Kismet/KismetSystemLibrary.h" #include "Utilities/CHelpers.h" #include "Utilities/CLog.h"
- #include "DrawDebugHelpers.h" 추가
C02_DrawDebug & BP_C02_DrawDebug 생성
C02_DrawDebug.h
#pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "C02_DrawDebug.generated.h" UCLASS() class U2212_03_API AC02_DrawDebug : public AActor { GENERATED_BODY() private: UPROPERTY(EditAnywhere, Category = "Settings") FVector InitLocation[5]; //시작위치 5곳 생성 UPROPERTY(EditAnywhere, Category = "Settings") FBox Box; //박스 생성 private: UPROPERTY(VisibleAnywhere) class UPointLightComponent* PointLight; //PointLight 생성 public: AC02_DrawDebug(); protected: virtual void BeginPlay() override; public: virtual void Tick(float DeltaTime) override; private: float EaseOutBounce(float x); private: FVector Location[5]; //위치 5곳 생성 };
C02_DrawDebug.cpp
#include "02_Profiler/C02_DrawDebug.h" #include "Global.h" #include "Components/PointLightComponent.h" AC02_DrawDebug::AC02_DrawDebug() { PrimaryActorTick.bCanEverTick = true; CHelpers::CreateComponent <UPointLightComponent>(this, &PointLight, "PointLight"); InitLocation[0] = FVector(0, 0, 0); InitLocation[1] = FVector(0, 1000, 0); InitLocation[2] = FVector(0, 500, 0); InitLocation[3] = FVector(0, 1500, 0); InitLocation[4] = FVector(500, 1000, 0); //Box의 중앙점을 (0,0,0)으로 잡음. Min은 앞쪽 좌하단, Max는 뒷쪽 우상단 Box = FBox(FVector(-50, -100, -50), FVector(50, 100, 50)); } void AC02_DrawDebug::BeginPlay() { Super::BeginPlay(); } void AC02_DrawDebug::Tick(float DeltaTime) { Super::Tick(DeltaTime); //내 위치 구하기 for (int32 i = 0; i < 5; i++) Location[i] = InitLocation[i] + GetActorLocation(); //박스, 사각형 점 빌보드로 그려줌, 구, 2D 원, (2번에서 3번까지 길이의)선 DrawDebugSolidBox(GetWorld(), Location[0] + Box.GetCenter(), Box.GetExtent(), FColor::Red); DrawDebugPoint(GetWorld(), Location[1], 100, FColor::Green); DrawDebugSphere(GetWorld(), Location[2], 100, 30, FColor::Blue); DrawDebugCircle(GetWorld(), Location[3], 100, 50, FColor::Magenta); DrawDebugLine(GetWorld(), Location[2], Location[3], FColor::Yellow, false, -1, 0, 10); //bPersistentLines(false면 1frame, true면 duration), LifeTime, DepthPriority, Thickness FVector location = Location[2]; location.X += 10; location.Y += 10; //location.Z += FMath::Sin(GetWorld()->GetTimeSeconds() * 5.0f) * 400.0f; location.Z += EaseOutBounce(FMath::Sin(GetWorld()->GetTimeSeconds() * 2.5f)) * 200.0f; DrawDebugCapsule(GetWorld(), location, 200, 50, FQuat::Identity, FColor::White); DrawDebugDirectionalArrow(GetWorld(), Location[3], location, 400, FColor::Black, false, -1, 0, 20); bool b = FMath::Sign(FMath::Cos(GetWorld()->GetTimeSeconds() * 5.0f)) >= 0; PointLight->SetVisibility(b); //PointLight가 SetVisibility로 깜박거리게 만들어준다. } //EaseOutBounce 함수. Easing함수 중 하나이다. float AC02_DrawDebug::EaseOutBounce(float x) { const float n1 = 7.5625f; const float d1 = 2.75f; if (x < 1.0f / d1) { return n1 * x * x; } else if (x < 2.0f / d1) { return n1 * (x -= 1.5f / d1) * x + 0.75f; } else if (x < 2.5f / d1) { return n1 * (x -= 2.25f / d1) * x + 0.9375f; } else { return n1 * (x -= 2.625f / d1) * x + 0.984375f; } }
DrawDebug - SolidBox, Sphere, Circle, Line, Capsule, DirectionalArrow
void DrawDebugSolidBox(const UWorld* InWorld, FVector const& Center, FVector const& Extent, FColor const& Color, bool bPersistent, float LifeTime, uint8 DepthPriority) void DrawDebugPoint(const UWorld* InWorld, FVector const& Position, float Size, FColor const& Color, bool bPersistentLines, float LifeTime, uint8 DepthPriority) void DrawDebugSphere(const UWorld* InWorld, FVector const& Center, float Radius, int32 Segments, FColor const& Color, bool bPersistentLines, float LifeTime, uint8 DepthPriority, float Thickness) void DrawDebugCircle(const UWorld* InWorld, FVector Center, float Radius, int32 Segments, const FColor& Color, bool PersistentLines, float LifeTime, uint8 DepthPriority, float Thickness, FVector YAxis, FVector ZAxis, bool bDrawAxis) void DrawDebugLine(const UWorld* InWorld, FVector const& LineStart, FVector const& LineEnd, FColor const& Color, bool bPersistentLines, float LifeTime, uint8 DepthPriority, float Thickness) void DrawDebugCapsule(const UWorld* InWorld, FVector const& Center, float HalfHeight, float Radius, const FQuat& Rotation, FColor const& Color, bool bPersistentLines, float LifeTime, uint8 DepthPriority, float Thickness) void DrawDebugDirectionalArrow(const UWorld* InWorld, FVector const& LineStart, FVector const& LineEnd, float ArrowSize, FColor const& Color, bool bPersistentLines, float LifeTime, uint8 DepthPriority, float Thickness)

실행화면

- 왼쪽에 PointLight가 깜박거린다.
'⭐ Unreal Engine > UE FPS TPS' 카테고리의 다른 글
[UE] Character Animation, Collsion (0) | 2023.03.08 |
---|---|
[UE] Character, GameMode (0) | 2023.03.07 |
[UE] Mesh, Log (0) | 2023.03.02 |
[UE] Properties (0) | 2023.02.28 |
[UE] Unreal C++ Settings, 파일이 안 열리는 문제해결 방법, 언리얼 코드 수정과 삭제 (0) | 2023.02.27 |
댓글
이 글 공유하기
다른 글
-
[UE] Character Animation, Collsion
[UE] Character Animation, Collsion
2023.03.08 -
[UE] Character, GameMode
[UE] Character, GameMode
2023.03.07 -
[UE] Mesh, Log
[UE] Mesh, Log
2023.03.02 -
[UE] Properties
[UE] Properties
2023.02.28
댓글을 사용할 수 없습니다.