필요한 개념
게임상에 메세지를 출력하기 위해(게임상, 출력로그상) CLog를 만듬. 자주 사용하는 클래스
BP에서는 PrintString()을 쓰면 게임상, 출력로그상에 같이 뜨는데
C에서는 따로 뜬다.
얘는 언리얼과 통신할게 아니라서 그냥 클래스를 만들면 되는데(만약 통신할게 있다면 UObject로 만들면 된다.)
또한 UObject로 상속받은 클래스가 아니면 컨텐츠 브라우저에 나타나지 않는다.
#include "CoreMinimal.h"
-> Generate 등 뜨지 않음(언리얼 에디터랑 통신안하니깐)
/**
*
*/
class UONLINE_03_CPP_API CLog // UONLINE_03_CPP_API -> 어느 프로젝트에 있는지 마킹위해
{
public:
CLog();
~CLog();
};
Tip) 언리얼 에디터와 통신한다는 것과 블푸랑 통신한다는 것은 의미가 다름
블푸랑 통신한다는 것 : 상속을 준 클래스거나 해당 클래스를 블푸로 직접 다루는 것
언리얼 에디터와 통신한다는 것 : 에디터에 나타나게 해주는것
printString()처럼 화면에 나타나게 해줄 수 있는 애가 Engine이라는 헤더에 있는데, 추가하면 거대해서 인텔리센스가 확 느려짐
그래서 한번만 컴파일 시키는 방식을 사용함
C++ 클래스를 화면에 배치시 보이지는 않지만 실행은 된다. -> 파생 BP 생성하고 배치하면 보인다.
UObject 이하는 ToString 함수를 가지고 있는데 이것은 해당 객체를 해당객체에 맞는 형식으로 출력 문자열을 리턴해주는 함수 이다.
UObject로 상속받아 직접 재정의로 구현도 가능하다.
보통은 게임 내 화면 출력보다는 로그에 띄우는 것을 많이 사용한다.
// 로그에 이런식으로 나옴 LogTemp: Display: 10
// L"%d" -> C의 Printf()와 동일
// UE_LOG(카테고리, ELogVerbosity(출력형태), 타입포맷, 값)
// 언리얼 출력로그 창 -> 필터 -> 경고, 오류, 카테고리 별로 볼 수 있다.
// LogTemp는 카테고리 중 한 종류이다.
// 카테고리는 만들어서 사용 가능
// DEFINE_LOG_CATEGORY_STATIC()
UE_LOG(LogTemp, Display, L"%d", InValue);
// 1 : 카테고리 이름 2 : 출력형태(Verbose 기본 지정(밑에서 바꿔서 해도 상관x)), 3 : 출력상황(어떠한 상황에서 메세지의 상황을 볼거냐(게임 플레이상황, 여러상황))
// All : 모든 상황에서 보겠다.(거의다 All을 씀)
DEFINE_LOG_CATEGORY_STATIC(GameProject, Display, All)
UE_LOG(GameProject, Display, L"%d", InValue);
로그 출력 결과를 보면
GameProject: Display: 10
으로 바뀌어있다.
Tip) 게임상의 실시간을 볼때는 게임상의 화면을 띄우고
값을 확인할때는 로그화면에 띄움
CLog.h
#pragma once
#include "CoreMinimal.h"
// 개발하다 보면 이 함수가 실행되는지 안되는지 보고 싶을때
#define PrintLine() {CLog::Log(__FUNCTION__, __LINE__);}
class UONLINE_03_CPP_API CLog
{
/*
printString()처럼 화면에 나타나게 해줄 수 있는 애가 Engine이라는 헤더에 있는데, 추가하면 거대해서 인텔리센스가 확 느려짐
그래서 한번만 컴파일 시키는 방식을 사용함
*/
public:
//======== 게임 화면에 띄우도록
// duration : 얼마만큼 시간, InColor : 출력할 색
// InValue : 출력할 값
// InKey : 해당 줄 번호(줄이 같다면 나중에 출력하는게 먼저 출력한 것을 지우고 나타남(Duration에 상관 없이)), -1이라면 계속 새로운 줄이 나타남
static void Print(int32 InValue, int32 InKey = -1, float Duration = 10.0f, FColor InColor = FColor::Blue);
static void Print(float InValue, int32 InKey = -1, float Duration = 10.0f, FColor InColor = FColor::Blue);
// 수정할 수 없도록(const), 복사방지(&)
static void Print(const FString& InValue, int32 InKey = -1, float Duration = 10.0f, FColor InColor = FColor::Blue);
static void Print(const FVector& InValue, int32 InKey = -1, float Duration = 10.0f, FColor InColor = FColor::Blue);
static void Print(const FRotator& InValue, int32 InKey = -1, float Duration = 10.0f, FColor InColor = FColor::Blue);
//========= 로그 화면에 띄우도록
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);
// NULL 체크해서 보여줌
static void Log(const UObject* InObject);
// 함수 보여주도록
// 함수이름, 라인수
static void Log(const FString& InFuncName, int32 InLineNumber);
};
CLog.cpp
#include "CLog.h"
#include "Engine.h" // 헤더가 되게 무거움, GEngine 사용위해
// 그래서 여기다 Engine.h 한번만 가져다 쓸라고 이러는 것임
// 1 : 카테고리 이름 2 : Verbose 기본 지정(밑에서 바꿔서 해도 상관x), 3 : 어떠한 상황에서 메세지의 상황을 볼거냐(게임 플레이상황, 여러상황)
// All : 모든 상황에서 보겠다.
DEFINE_LOG_CATEGORY_STATIC(GameProject, Display, All)
void CLog::Print(int32 InValue, int32 InKey, float Duration, FColor InColor)
{
// GEngine : 전역객체
// AddOnScreenDebugMessage : 화면에 띄워주는 애
// FString::FromInt : Int->String으로
// 얘는 BP에서 PrintString()이랑은 다르게 Log에는 안나타남
GEngine->AddOnScreenDebugMessage(InKey, Duration, InColor, FString::FromInt(InValue));
}
void CLog::Print(float InValue, int32 InKey, float Duration, FColor InColor)
{
// float을 바꾸려면 SanitizeFloat(사니티즈플롯)으로 해야 문자열로 바꿀수 있음
GEngine->AddOnScreenDebugMessage(InKey, Duration, InColor, FString::SanitizeFloat(InValue));
}
void CLog::Print(const FString& InValue, int32 InKey, float Duration, FColor InColor)
{
GEngine->AddOnScreenDebugMessage(InKey, Duration, InColor, InValue);
}
void CLog::Print(const FVector& InValue, int32 InKey, float Duration, FColor InColor)
{
// 수학 함수들은 ToString()이라는 함수를 가지고 있다.
GEngine->AddOnScreenDebugMessage(InKey, Duration, InColor, InValue.ToString());
}
void CLog::Print(const FRotator& InValue, int32 InKey, float Duration, FColor InColor)
{
GEngine->AddOnScreenDebugMessage(InKey, Duration, InColor, InValue.ToString());
}
void CLog::Log(int32 InValue)
{
// GLog->Log()
// GLog를 통해서 로그 출력도 가능하지만 카테고리를 지정할 수 없어서 간단히 쓸때만 사용
// 잘 안씀
// 얘를 쓴다.
// UE_LOG() : 카테고리와 표현 형식 등을 지정해 출력할 수 있는 매크로
// Verbosity : 어떤 형태로 메세지를 보여줄 것인지
/*
namespace ELogVerbosity
{
enum Type
{
NoLogging = 0, // 사용하지 않음
Fatal, // 중대한 에러 발생 -> 빨간색 띄울떄
Error, // 에러 발생 -> 빨간색 띄울떄
Warning, // 경고 발생 -> 노란색 띄울때
Display, // 일반적인 메세지(Saved/Log 파일에 기록됨) -> 많이 사용
Log, // Saved/Log 파일에 기록하는데, 따로 로그화면에 띄우지 않음
Verbose, // 자세한 메세지를 로그 파일에 기록
VeryVerbose, // 자세한 메세지를 로그 파일에 기록
All = VeryVerbose,
NumVerbosity,
VerbosityMask = 0xf,
SetColor = 0x40,
BreakOnLog = 0x80,
}
}
*/
// 로그에 이런식으로 나옴 LogTemp: Display: 10
// L"%d" -> C의 Printf()와 동일
// UE_LOG(카테고리, ELogVerbosity, 타입형태, 값)
// 언리얼 출력로그 창 -> 필터 -> 경고, 오류, 카테고리 별로 볼 수 있다.
// LogTemp는 카테고리 중 한 종류이다.
// 카테고리는 만들어서 사용 가능
// DEFINE_LOG_CATEGORY_STATIC()
UE_LOG(GameProject, Display, L"%d", InValue);
}
void CLog::Log(float InValue)
{
UE_LOG(GameProject, Display, L"%f", InValue);
}
void CLog::Log(const FString& InValue)
{
// *InValue : 문자열 배열 리턴
UE_LOG(GameProject, Display, L"%s", *InValue);
}
void CLog::Log(const FVector& InValue)
{
// ToString() 리턴 값은 FString이어서 *를 해줘야 문자열 배열 리턴
UE_LOG(GameProject, Display, L"%s", *InValue.ToString());
}
void CLog::Log(const FRotator& InValue)
{
UE_LOG(GameProject, Display, L"%s", *InValue.ToString());
}
void CLog::Log(const UObject* InObject)
{
FString str;
// Object가 있을 경우 이름 연결
if (!!InObject)
str.Append(InObject->GetName());
str.Append(!!InObject ? "Not Null" : "Null");
UE_LOG(GameProject, Display, L"%s", *str);
}
void CLog::Log(const FString& InFuncName, int32 InLineNumber)
{
FString str;
str.Append(InFuncName);
str.Append(", ");
str.Append(FString::FromInt(InLineNumber));
UE_LOG(GameProject, Display, L"%s", *str);
}
C01_Log.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C01_Log.generated.h"
UCLASS()
class UONLINE_03_CPP_API AC01_Log : public AActor
{
GENERATED_BODY()
public:
AC01_Log();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
private:
float Time;
};
C01_Log.cpp
#include "C01_Log.h"
#include "Global.h"
AC01_Log::AC01_Log()
{
PrimaryActorTick.bCanEverTick = true;
}
void AC01_Log::BeginPlay()
{
Super::BeginPlay();
CLog::Print(10);
CLog::Print(20, 1);
CLog::Print(30, 2, 20.0f);
// 30의 줄인 2번째 줄을 40이 대체
CLog::Print(40, 2, 20.0f);
CLog::Print("Unreal GamePlay");
CLog::Print(GetActorLocation());
CLog::Print(GetActorRotation());
CLog::Log(10);
CLog::Log(PI);
CLog::Log("Unreal GamePlay");
CLog::Log(GetActorLocation());
CLog::Log(GetActorRotation());
// 클래스가 NULL이 아닌지(UObejct를 상속 받는 것중에)
CLog::Log(this);
// 컴파일될 때 해당 매크로가 소속되어 있는 정보를 나타남
// __FUNCTION__ : 함수 이름(현재 실행중인 함수명이 나타남)
// __FILE__ : 파일의 경로(현재 소스의 파일명을 나타냄)
// __LINE__ : 해당 라인(현재 소스가 실행중인 라인 나타냄)
//CLog::Log(__FUNCTION__, __LINE__);
PrintLine();
}
void AC01_Log::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// 델타타임은 이전 프레임과 현재 프레임간의 시간차다.(속도 같도록 보장)
Time += DeltaTime;
// 매 프레임마다 누적 시간
// 델타 타임을 누적하면 시작부터 현재까지 게임이 흐른시간이다.
// 줄에 ID를 넣으면 그 줄에서 계속 교체가 일어남
// 아이디를 안넣으면(-1) 계속 밑으로 쭉 나타남
CLog::Print(Time, 3);
}
결과
출력로그 및 게임창에 텍스트가 뜬 것을 볼 수 있다.
'Unreal Engine 4 > C++' 카테고리의 다른 글
<Unreal C++> 13 - Actor Begin & End Overlap (0) | 2022.04.07 |
---|---|
<Unreal C++> 12 - DrawDebug (0) | 2022.04.07 |
<Unreal C++> 10 - UAnimInstance (0) | 2022.04.07 |
<Unreal C++> 9 - PlayerInputComponent (0) | 2022.04.04 |
<Unreal C++> 8 - Player (0) | 2022.04.04 |