로그 출력하기

 

작성버전 :: 4.20.3

 

로그는 개발중에 여러가지 피드백을 얻기 위해서 중요한 도구다. 그렇기 때문에 항상 새로운 언어, 새로운 엔진 등을 배울 때는 거기서 어떤 방식으로 로그를 출력하는지 알아두는 것이 좋다. 이번에는 언리얼 엔진 4에서 로그를 출력하는 방법을 알아보자.

 

 

로그가 출력되는 출력 로그 탭 열기

 

 

 

우선은 로그를 출력하는 법을 배운 이후에 로그가 출력될 로그 탭을 여는 방법에 대해서 배워보자.

 

- 창 -> 개발자 툴 -> 출력 로그 (Window -> Developer Tools -> Output Log) 항목을 선택한다.

 

 

 

지시대로 출력 로그(Output Log) 항목을 선택하면 출력 로그 탭이 열리는 것을 확인할 수 있다. 에디터에서 우리가 출력하도록 명령한 로그들은 저 출력 로그 탭에서 출력될 것이다.

 

 

간단한 사용법

 

UE_LOG(LogTemp, Log, TEXT("Log Message"));

 

위의 코드를 사용하는 것으로 간단하게 로그를 출력할 수 있다. 언리얼에서 로그 기능은 매크로 함수로 정의 되어있으며, 매개변수는 앞에서부터 순서대로 로그 카테고리(Log Category), 로그 상세 수준(Log Verbosity Level), 로그 내용이다.

 

 

로그 상세 수준(Log Verbosity Level)

 

로그 상세 수준의 종류는 다음과 같다.

 

  • Fatal
Fatal 수준 로그는 항상 콘솔 및 로그 파일에 출력되며 로그가 비활성화된 경우에도 작동이 중단된다.
  • Error
Error 수준 로그는 콘솔 및 로그 파일에 출력되며, 이 로그는 기본적으로 빨간색으로 표시된다.
  • Warning
Warning 수준 로그는 콘솔 및 로그 파일에 출력되며, 이 로그는 기본적으로 노란색으로 표시된다.
  • Display
Display 수준 로그는 콘솔및 로그 파일에 출력된다.
  • Log
Log 수준 로그는 로그 파일에는 출력되지만, 게임 내의 콘솔에서는 출력되지 않지만, 에디터의 출력 로그 탭을 통해서는 계속 출력된다.
  • Verbose
Verbose 수준의 로그는 로그 파일에는 출력되지만, 게임 내의 콘솔에는 출력되지 않는다. 일반적으로 자세한 로깅 및 디버깅에 사용된다.
  • VeryVerbose
VeryVerbose 수준의 로그는 로그 파일에는 출력되지만, 게임 내의 콘솔에는 출력되지 않는다. 이 수준의 로그는 일반적으로 대량의 로그를 출력하는 상세한 로깅에 사용된다.

 

 

로그 상세 수준 중에 자주 사용될 에러, 경고, 로그 수준을 사용해서 로그를 출력하면 위의 이미지와 같이 로그가 출력된다.

 

Fatal 수준의 로그는, 출력되거나 컴파일 혹은 빌드할 때 코드가 실행되는 상황이라면 충돌 리포트를 띄우지만 이것은 의도된 충돌이기 때문에 로그 파일이나 충돌 호출 스택(Crash call stack)을 확인하면 된다.

 

 

 

 

 

로그 카테고리(Log Category)

 

로그 카테고리는 출력된 로그가 어떤 시스템에서 발생한 로그인지 알려주는 역할을 한다. 위의 간단한 사용법 파트에서는 이 로그 카테고리에 LogTemp를 넣어서 사용했는데, 이것은 특정한 카테고리에 속하지 않고 임시로 띄우는 로그라는 의미다. 언리얼 엔진에서는 이러한 카테고리를 90개 이상을 기본적으로 제공한다.

 

 

 

어떤 카테고리에서 로그가 발생했는지 알려줄 수 있기 때문에 로그 출력 코드를 작성할 때, 제대로 된 카테고리를 분류해서 넣어주기만 한다면 로그가 제공하는 정보가 좀 더 상세해질 수 있다.

 

 

커스텀 로그 카테고리(Custom Log Category)

 

언리얼 엔진에서 제공하는 로그 카테고리 이외에 개발자가 필요한 카테고리를 직접 만들어서 사용할 수 있다.

 

만약, 당신의 프로젝트 이름이 MyGame이라면 비주얼 스튜디오의 솔루션 탐색기에서 MyGame.h와 MyGame.cpp를 찾아서 다음과 같이 추가하면 된다.

 

MyGame.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"

DECLARE_LOG_CATEGORY_EXTERN(LogMyGame, Log, All);

 

MyGame.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyGame.h"
#include "Modules/ModuleManager.h"

IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, MyGame, "MyGame" );

DEFINE_LOG_CATEGORY(LogMyGame);

 

그리고 추가한 로그 카테고리를 사용할 때는 아래의 예시 코드와 같이 사용할 소스 파일에 MyGame.h를 포함한뒤 사용하면 된다.

 

MyActor.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyActor.h"
#include "Engine.h"
#include "MyGame.h"

// Sets default values
AMyActor::AMyActor()
{
     // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    UE_LOG(LogMyGame, Log, TEXT("My Log"));
}

 

 

 

 

 

로그 포맷(Log Formatting)

 

로그를 작성할 때, 로그의 내용이 고정되어 있는 경우보다, 상황이나 데이터의 내용에 따라 유동적으로 바뀌는 경우가 많다. 그렇기 때문에 간단한 사용법 파트의 예시처럼 고정된 문자열 방식이 아니라 포맷팅을 통해서 원하는 데이터의 내용 등을 고정된 로그의 내용과 함께 출력되도록 해야한다. 언리얼 엔진에서 로그 포맷팅을 하는 방법은 CPP에서 문자열 포맷팅하는 방법과 같다.

 

일반 메시지

UE_LOG(LogTemp, Log, TEXT("Log Message"));

 

FString

 

언리얼 엔진에서 기본적으로 사용되는 문자열 클래스는 FString이다. 로그에서 %s는 TCHAR* 타입을 받는다. 이것은 *FString에 대응한다.

UE_LOG(LogTemp, Log, TEXT("Character Name :: %s"), *MyCharacter->GetName());

 

bool

UE_LOG(LogTemp, Log, TEXT("Character is Die :: %s"), MyCharacter->IsDie ? TEXT("true") : TEXT("false"));

 

int

UE_LOG(LogTemp, Log, TEXT("Character HP :: &d"), MyCharacter->Hp);

 

float

UE_LOG(LogTemp, Log, TEXT("Character Stamina :: %f"), MyCharacter->Stamina);

 

FVector

 

FVector는 언리얼 엔진에서 위치를 표현하는 클래스이다.

UE_LOG(LogTemp, Log, TEXT("Character Location :: %s"), MyCharacter->GetActorLocation().ToString());

 

FName

UE_LOG(LogTemp, Log, TEXT("Character FName :: &d"), MyCharacter->GetFName().ToString());

 

여러 자료형 한번에 로그로 출력하기

UE_LOG(LogTemp, Log, TEXT("CharacterName :: &s / HP :: &d / Stamina :: %f"), *MyCharacter->GetName(), MyCharacter->Hp, MyCharacter->Stamina);

 

추가로...

 

bool 같은 논리 변수는 로그로 출력하는 과정이 조금 번거롭기 때문에, 로그를 자주 사용한다면 이러한 번거로운 과정을 간소화하기 위해서 로그를 위한 클래스로 래핑해서 사용하는 것도 추천해볼만하다.

 


 

참고

 

Unreal Engine 4 Wiki - Logs, Printing Messages To Yourself During Runtime (https://wiki.unrealengine.com/index.php?title=Logs,_Printing_Messages_To_Yourself_During_Runtime&action=edit)

 

 

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

프로그래밍 작업시 헤더(Header) 포함(Include) 문제

 

작성버전 :: 4.20.3

 

언리얼 엔진4(이하 언리얼 엔진 혹은 언리얼)에서의 프로그래밍은 C++기반으로 구성되어 있기 때문에 다른 헤더 파일에 정의된 클래스 등을 사용하기 위해서는 헤더를 포함하는 전처리가 필수적이다.

 

일반적인 C++ 프로젝트에서 헤더가 꼬이거나 중복 호출되는 경우만 조심하면 주의하면 되고 헤더의 순서는 별로 중요하지 않은 것에 비해서 언리얼에서의 헤더 포함은 약간 복잡하고 귀찮은데다가 버그까지 있다.

 

언리얼 엔진이 아닌 다른 C++ 프로젝트에서는 프로그래밍 작업 도중에 필요한 헤더가 생긴다면 상단의 전처리기들 아래에 필요한 헤더의 포함 선언을 추가할 것이다. 하지만 언리얼에서는 헤더 포함의 위치가 중요하다.

 

 

 

만약 AMyActor 클래스에서 AMyActorComponent를 사용하기 위해서 MyActorComponent.h의 선언을 일반적인 C++ 프로젝트에서 하듯이 MyActor.h의 헤더 포함 리스트 제일 아래에 추가하면 위의 이미지처럼 신텍스 에러(E0077 this declaration has no storage class or type specifier)가 발생하고 에디터에서의 컴파일 역시 실패한다.

 

언리얼에서는 다른 헤더를 포함할 때, 항상 generated.h 헤더보다 위쪽에 포함 선언을 추가해야 된다.

 

 

 

위의 이미지처럼 새롭게 추가하는 헤더 포함 선언을 generated.h 헤더 선언 위로 올리고 수정한 소스 파일을 저장하면 대부분은 신텍스 에러가 사라진다. 하지만 여기서 고질적인 문제가 발생하는데 꽤나 높은 빈도로 정상적으로 generated.h 위쪽으로 헤더 포함 선언을 옮겼는데도 불구하고 아래의 이미지처럼 신텍스 에러가 사라지지 않는 경우가 있다.

 

 

 

이러한 문제는 인텔리전스 버그로 실제 컴파일에서는 전혀 문제가 되지 않는다. 실제로도 에디터에서 컴파일을 해보면 전혀 문제 없이 컴파일이 진행되는 것을 알 수 있다. 이런 인텔리전스 버그는 잠시 후에 없어지기도 하고, 에디터에서 컴파일하거나, 비주얼 스튜디오나 언리얼을 재실행 하는 것으로도 없어진다.

 

이런 헤더 순서 문제가 매우 중요함에도 불구하고 언리얼 엔진 레퍼런스 문서에서는 쉽게 찾을 수 없는게 문제다.

 

 

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

+ Recent posts