[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