언리얼 엔진 Actor의 라이프 사이클

주상돈·2025년 2월 11일

TIL

목록 보기
28/53

Actor 클래스에 로그 (Log) 추가하기


게임 개발 중 특정 함수가 제대로 호출되는지, 변수에 어떤 값이 들어있는지를 빠르게 확인해야 할 때는 로그 메시지가 큰 도움이 된다. 언리얼 엔진에서는 UE_LOG 매크로를 사용해 Output Log 창에 메시지를 남길 수 있다.

1️⃣ BeginPlay() 함수에 로그 추가하기

  • 아래는 액터의 BeginPlay() 함수가 호출되는 시점을 확인하기 위해 로그를 출력하는 코드 예시이다.
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Item.generated.h"

UCLASS()
class SPARTAPROJECT_API AItem : public AActor
{
		GENERATED_BODY()
	
public:	
		AItem();

protected:
		USceneComponent* SceneRoot;
		UStaticMeshComponent* StaticMeshComp;
		
		// BeginPlay 함수를 다시 선언
		virtual void BeginPlay() override;
};

Item.h

#include "Item.h"

AItem::AItem()
{
		// Component 설정
		SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
		SetRootComponent(SceneRoot);
	
		StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
		StaticMeshComp->SetupAttachment(SceneRoot);
	
		static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshAsset(TEXT("/Game/Resources/Props/SM_Chair.SM_Chair"));
		if (MeshAsset.Succeeded())
		{
			StaticMeshComp->SetStaticMesh(MeshAsset.Object);
		}
	
		static ConstructorHelpers::FObjectFinder<UMaterial> MaterialAsset(TEXT("/Game/Resources/Materials/M_Metal_Gold.M_Metal_Gold"));
		if (MaterialAsset.Succeeded())
		{
			StaticMeshComp->SetMaterial(0, MaterialAsset.Object);
		}
}

void AItem::BeginPlay()
{
		Super::BeginPlay();
		
		// BeginPlay 호출 시점을 로그로 확인
	  UE_LOG(LogTemp, Warning, TEXT("My Item appears!!"));
}

Item.cpp

  • UE_LOG(LogTemp, Warning, TEXT("My Item appears!!"))
    • 로그 카테고리 (Log Category): 여기서는 LogTemp라는 임시 카테고리를 사용했다.
    • 로그 수준 (Log Level): Warning을 사용하면, 노란색 글씨로 강조되어 출력된다. 이 외에도 Log, Display, Error 등 다양한 수준이 있다.
      • Display: 일반적인 실행 흐름이나 상태 확인 메시지 (흰색)
      • Warning: 예상치 못한 동작이나 잠재적인 문제 (노란색)
      • Error: 즉시 수정이 필요한 심각한 문제 (빨간색)
    • 출력할 메시지: My Item appears!!라는 문자열이 출력된다.

2️⃣ 고유한 카테고리 정의하고 로그 추가하기

  • 프로젝트 규모가 커질수록 모든 로그를 LogTemp로 찍으면 구분이 어렵습니다. 이럴 때는 DEFINE_LOG_CATEGORY를 사용해 고유한 카테고리를 만들어 사용하는 것이 좋다.
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Item.generated.h"

// "LogSparta"라는 이름으로 로그 카테고리 선언
DECLARE_LOG_CATEGORY_EXTERN(LogSparta, Warning, All);

UCLASS()
class SPARTAPROJECT_API AItem : public AActor
{
		GENERATED_BODY()
	
public:	
		AItem();

protected:
		USceneComponent* SceneRoot;
		UStaticMeshComponent* StaticMeshComp;
		
		virtual void BeginPlay() override;
};

Item.h

  • DECLARE_LOG_CATEGORY_EXTERN(LogSparta, Warning, All);
    • 헤더 파일에서 로그 카테고리를 선언
    • LogSparta: 카테고리 이름 (사용자가 지정).
    • Warning: 이 카테고리를 사용할 때 기본적으로 Warning 이상의 로그만 출력하도록 설정
    • All: 필요하면 나중에 모든 로그를 활성화할 수 있도록 허용
  • 이후 다른 클래스에서도 LogSparta 카테고리를 사용하고 싶다면 이 헤더 파일(Item.h)을 포함해야 합니다. 보통은 이런 로그 카테고리를 여럿이 공유하기 때문에, 별도의 공용 헤더에 선언해 두는 경우가 많다.
#include "Item.h"

// "LogSparta" 카테고리 정의 (헤더에서 선언한 것을 실제로 구현)
DEFINE_LOG_CATEGORY(LogSparta);

AItem::AItem()
{
		// Component 설정
		SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
		SetRootComponent(SceneRoot);
	
		StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
		StaticMeshComp->SetupAttachment(SceneRoot);
	
		static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshAsset(TEXT("/Game/Resources/Props/SM_Chair.SM_Chair"));
		if (MeshAsset.Succeeded())
		{
			StaticMeshComp->SetStaticMesh(MeshAsset.Object);
		}
	
		static ConstructorHelpers::FObjectFinder<UMaterial> MaterialAsset(TEXT("/Game/Resources/Materials/M_Metal_Gold.M_Metal_Gold"));
		if (MaterialAsset.Succeeded())
		{
			StaticMeshComp->SetMaterial(0, MaterialAsset.Object);
		}
}

void AItem::BeginPlay()
{
	Super::BeginPlay();
	
	// 기존 LogTemp
	UE_LOG(LogTemp, Warning, TEXT("My Item appears!!"));
	// 새로 만든 LogSparta
	UE_LOG(LogSparta, Error, TEXT("My Log!!"));
}
  • DEFINE_LOG_CATEGORY(LogSparta);
    • .cpp 파일에서 로그 카테고리를 구현(정의)한다.
  • 이제 LogSparta라는 카테고리를 통해 로그 메시지를 좀 더 체계적으로 구분할 수 있다.

//생성자 -메모리에 생김. 딱 한번 호출.
// PostInitializeComponents() - 컴포넌트가 안성된 직후 호출. 컴포넌트끼리 데이터 주고받기, 상호작용
// BeginPlay() - 배치(Spawn)
// Tick(float DeltaTime) - 매 프레임 마다 호출 됨.
// Destroyed() - 삭제 되기 직전에 호출된다.
// EndPlay() - 게임 종료, 파괴 (Destroyed()), 레벨 전환

0개의 댓글