TIL_036: 언리얼 / 솔루션 관계, Object / Actor Class, Scene

김펭귄·2025년 9월 21일

Today What I Learned (TIL)

목록 보기
36/139

오늘 학습 키워드

  • 언리얼 디렉토리 구조

  • 솔루션 디렉토리 구조

  • 솔루션과 언리얼의 관계

  • Build Configuration

  • Intellisense

  • 빌드로 생성된 파일

  • 빌드로 생성된 파일

  • Live Coding

  • 빌드 꼬임 해결법

  • Object / Actor Class

  • 액터 클래스 코드

  • Scene 컴포넌트

1. 언리얼 디렉토리 구조

  • Source: C++로 작성한 코드가 저장되는 디렉토리

  • Content: 게임 에셋, 블루프린트, sound, material 등을 저장 및 관리하는 디렉토리

  • .sln: visual stuio 솔루션 파일

  • .uproject: 언리얼 에디터 파일

  • Binaries: C++ 코드를 빌드하면 생성되는 실행 파일(.exe, .dll 등)이 저장
    이 폴더를 삭제하면 다음 빌드 시 모든 바이너리를 처음부터 다시 생성해야 하므로 시간이 더 오래 걸릴 수 있다.

  • Config: 게임플레이, 렌더링, 입력 등의 설정을 담은 .ini 파일

  • DerivedDataCache: 에셋, 쉐이더 등을 빠르게 처리하기 위한 캐시 파일

  • Intermediate: C++ 컴파일 과정에서 생성되는 임시 파일 및 빌드 중간 결과물.

  • Saved: 자동 저장 파일, 로그 (.log), 크래시 덤프 등이 모여 있다. 게임·에디터가 비정상 종료되었을 때, 이 폴더 안의 로그 파일을 확인해 문제를 진단할 수 있다.

2. 솔루션 디렉토리 구조

  • 솔루션 파일이 빌드를 수월하게 하기 위해 재구성한 가상 디렉토리 구조

  • Engine: 언리얼 엔진 자체 소스 코드(코어코드)와 리소스가 담긴 곳.
    에디터 작동, 엔진 코어 관련 코드가 포함되어 있고 수정하여 엔진 수정도 가능

  • Games: 우리가 만든 프로젝트 코드가 모두 들어 있는 중요한 폴더.

내부에는 Source, Config, .uproject 파일 등이 있으며(위에서 본 언리얼 디렉토리와 동일), C++로 작성하는 게임 로직을 이 폴더에서 가장 많이 다룬다.

  • Programs: 엔진 동작에 필요한 유틸리티 프로그램이나 서버 모듈이 담겨 있다.

  • Rules: 엔진과 게임 등 각 모듈의 빌드 규칙을 정의해 놓은 파일들.
    모듈 의존성, 플러그인 활성화 여부, 빌드 대상 등을 제어.

  • Visualizers 폴더: Visual Studio 디버거에서 언리얼 엔진의 복잡한 자료구조 (예: FVector, FString)를 보다 읽기 쉽게 시각화할 수 있도록 도와주는 설정 파일

Games 디렉토리 세부 설명

  • Config: .ini 파일을 통해 에디터와 게임의 초기 상태를 지정

    • DefaultEditor.ini: 에디터 환경 설정 (뷰포트, UI 등)

    • DefaultEngine.ini: 엔진 전반 설정 (렌더링, 네트워킹 등)

    • DefaultGame.ini: 게임플레이 관련 설정 (게임 모드, 플레이어 컨트롤러 클래스 등)

    • DefaultInput.ini: 키보드·마우스·패드 등의 기본 입력 바인딩

  • Source: 실제 C++ 소스 코드(.cpp, .h). 빌드 설정 관련 주요 파일도 포함.

    • .Build.cs: 해당 프로젝트에 필요한 모듈, 라이브러리, 종속성 등을 정의

    • .Target.cs, .Target.cs: 각각 게임 실행용, 에디터용 빌드 방식을 정의

3. 솔루션과 언리얼의 관계

  • 솔루션에서 코드 작성 후 저장한다고 언리얼에 반영되지 않음

  • 솔루션 수정 -> 빌드 (컴파일 + 링크) -> (.exe, .dll, ..)파일 생성 -> 언리얼 에디터가 이 파일들 사용

  • 따라서 솔루션 파일을 빌드해서 파일을 생성해야 언리얼 엔진에 반영됨

  • 솔루션 빌드할 때는 언리얼 에디터를 종료하고 해야함.
    에디터가 이전의 파일을 잡고 있기 때문에 켜놓은 상태로 빌드하면 에러날 수 있다.

4. Build Configuration

  • 왼쪽의 칸은 빌드 모드(Configuration)를, 오른쪽은 실행 환경(플랫폼)을 선택

빌드 구성 (Configuration) 종류

  • DebueGame과 DebueGame Editor는 디버깅을 하기 위한 모드.
    디버깅을 하기 위한 것이므로 게임이 조금 무거워짐

  • Development와 Development Editor는 가장 일반적인 모드.
    디버깅 정보는 좀 축소화되어 게임이 가벼워짐. 대신 디버깅면에서는 약함

  • 따라서 디버깅을 위한 목적이면 전자를, 일반적으로는 후자 모드를 선택. 그리고 여기서 게임파일로만 할거냐, 에디터까지 포함해서 할거냐를 또 선택하는 것.

DebugGame

  • 언리얼 에디터 없이, 독립된 게임 실행 파일 환경에서 디버깅할 때 사용

  • 엔진 코드는 디버깅이 제한적, 게임 로직만 효과적으로 디버깅

DebugGame Editor

  • 에디터 환경에서 게임 로직을 디버그하기 편한 설정

  • 에디터 플레이 중에 C++ 로직을 추적하거나 브레이크포인트를 걸어볼 수 있다

Development

  • 디버그 정보를 최소화해 실행 속도를 높인 개발용 빌드

  • 독립 실행 파일 환경 테스트·개발 단계에서 주로 사용

Development Editor

  • 에디터에서도 개발·테스트를 원활히 할 수 있도록 구성된 빌드 모드

  • Live Coding 사용 시나리오와 궁합이 좋아 많이 사용됨

Shipping

  • 배포할 때 사용하는 릴리스 빌드

  • 디버그 정보 모두 제거하여, 성능 극대화

플랫폼 (Platform) 설정

  • 기본적으로 Win64가 선택되어 있으며, 이는 Windows 64비트 환경을 의미

  • 모바일 (Android, iOS), 콘솔 (PS, Xbox 등)로 빌드하려면 해당 플랫폼용 SDK를 추가로 설치해야 함

5. Intellisense

  • 빌드 하고, 오류 목록은 빌드로만 보기. Intellisense는 코드 편집에 관한 에러를 보여주는 것으로, 빌드에러와는 큰 상관이 없다.

6. 빌드로 생성된 파일

  • 빌드 후 Binaries 폴더에 파일이 생성된다

exe 파일

  • 게임 자체를 실행할 때 사용하는 실행 파일

  • Debug Configuration 종류에 따라 실행 파일에 디버깅 정보가 들어갈수도 있다.

DLL 파일

  • "Dynamic Link Library"의 줄임말로, "동적 링크 라이브러리".

  • 프로그램에서 필요한 함수, 데이터, 리소스(아이콘, 이미지 등)를 담아두는 라이브러리 파일.

  • 여러 프로그램이(에디터 등) 동시에 참조할 수 있고, 게임 파일 실행 중에도 메모리로 불러와서 활용.

  • 코드 재사용, 메모리 절약, 프로그램 모듈화를 위해 사용됨.

PDB 파일

  • "Program Database"의 약자로 디버깅 심볼 정보를 담음.

  • 프로그램이 크래시할 때 코드의 위치 등을 특정하는 데 사용된다.

modules 파일

  • 프로젝트에 포함된 모듈 목록을 담은 파일.

  • 에디터가 어떤 DLL을 로딩할지 지정.

7. Live Coding

  • 근데 코드 수정할 때마다 에디터 끄고, 빌드하고, 프로젝트 실행하여 에디터 열고를 반복하는 것은 귀찮음

  • 그래서 에디터에서 live coding 기능을 이용해 편리하게 사용 가능

  • 에디터를 켜놓은 채로 코드 수정하고 저장한 다음, live coding 버튼을 클릭만 하면 알아서 빌드하고 에디터에도 변경사항이 적용됨

  • 근데 사실 잘 작동이 안 되는 상황들이 있어 기존의 방법 사용하는 것을 추천

8. 빌드 꼬임 해결법

  • 빌드 문제 발생 시 Binaries, DerivedDataCache, Intermediate 폴더를 삭제하고 다시 빌드를 시도하면 문제를 해결할 수도 있다. 이 세 폴더는 어차피 빌드하면 다시 생성됨.

  • 그리고 generate해주면 다시 생성되고 에디터 실행하면 대부분 해결됨

  • 그래도 안 되면 에디터 끄고 솔루션 파일 열어서 솔루션 정리 후 빌드 해주면 대부분은 다 해결된다

9. Object / Actor Class

Object Class (UObject)

  • UObject는 언리얼 엔진에서 모든 클래스의 최상위 부모 클래스

  • 월드(레벨)에 배치될 수 없고 주로 데이터나 로직만 담당

  • 예) 컴포넌트, 플레이어 능력치, AI 정보, 게임 설정 값, 임시 계산 로직 등, 화면에 보이지 않는 데이터나 로직을 처리

언리얼 공식 오브젝트 문서

Actor (AActor)

  • AActor는 UObject를 상속한 클래스로, 월드에 배치(Spawn) 가능한 클래스

  • 배치 가능하므로 위치, 회전, 크기 등 공간적 정보를 가지고 있고, 여러 컴포넌트 (Component)를 추가로 붙일 수 있다.

  • 보이고 상호작용하는 캐릭터, 적 몬스터, 무기, 조명, 파티클 효과 등

언리얼 공식 액터 문서

10. 액터 클래스 코드

헤더파일

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Item.generated.h"
  • CoreMinimal.h : 언리얼에서 가장 기본이 되는 헤더. 자료형, 매크로, 함수, 로그 등 여러 기능을 담당.

  • GameFramework/Actor.h : AActor 정보 가지고 있는 헤더파일. 액터 클래스 선언 가능하게 함

  • Item.generated.h : 언리얼 헤더툴(UHT)이 자동 생성하는 코드를 포함하는 것으로, 항상 헤더의 마지막 줄에 위치해야 함. 다른 곳에 있으면 컴파일 에러.

UCLASS()
class SPARTPROJECT_API AItem : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AItem();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
};
  • UCLASS : 해당 클래스를 언리얼 엔진의 리플렉션 시스템에 등록하기 위한 선언부. UObject 기반 클래스로 처리할 수 있게 표시

  • GENERATED_BODY : 컴파일 시 UHT가 자동으로 생성하는 코드 조각을 포함하여, 리플렉션 메타데이터 및 UObject 관련 필수 코드(생성자, 직렬화 등)를 클래스에 삽입

  • 이 둘을 통해 UHT가 클래스를 분석하여 메타데이터를 생성하고, 런타임에 언리얼 엔진이 해당 클래스를 인식하고 다양한 엔진 기능(가비지 컬렉션, 블루프린트 연동, 네트워크 복제 등)을 지원할 수 있게 함

  • AItem, AActor : 클래스 앞에 접두어 붙이는 규칙이 있음.
    A (Actor 계열), U (Object 계열), F(구조체), T (템플릿), E (열거형) 등

  • SPARTAPROJECT_API : 이 클래스를 모듈 (현재 모듈은 SpartaProject) 외부에서도 클래스를 사용할 수 있게 하기 위한 매크로입니다

  • AItem() : 액터의 생성자. 객체가 메모리에 생성될 때 호출됨.

  • BeginPlay() : 액터가 월드에 완전히 배치되고, 게임이 플레이되거나 플레이중이라면 실행됨.

  • Tick(float DeltaTime) : 매 프레임마다 자동으로 호출됨

cpp 파일

#include "Item.h" 	// 헤더 파일

AItem::AItem()
{
	PrimaryActorTick.bCanEverTick = true;	// Tick관련
}
void AItem::BeginPlay()
{
	Super::BeginPlay();			// 부모클래스(Super)의 함수 사용
	
}
void AItem::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);		// 부모클래스(Super)의 함수 사용

}

11. Scene 컴포넌트

  • 하나의 Actor에 여러 컴포넌트를 사용하게 되는데, 이때 각 컴포넌트마다 root가 필요할 수 있음

  • 이때 주로 scene 컴포넌트를 root 컴포넌트로 사용. 트랜스폼 속성만 가지는 비시각적인 컴포넌트이기 때문.

profile
반갑습니다

0개의 댓글