Unreal Track 1기 [25.01.22] - C++와 Unreal Engine으로 3D 게임 개발 :: 1주차 (2)

chooha·2025년 1월 22일

TIL

목록 보기
26/60

< Actor를 상속한 클래스 >

1. 헤더 파일

▸ 파일 상단

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Item.generated.h"
  • CoreMinimal.h
    언리얼 엔진에서 자주 사용하는 기본 타입(FString, TArray 등)과 매크로(UE_LOG 등), 각종 유틸 함수들이 정의되어 있음

  • Item.generated.h
    언리얼 엔진의 리플렉션 시스템에서 필요한 코드를 자동 생성하기 위한 매크로 (나중에 정리)

▸ 클래스 선언부

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

protected:
		virtual void BeginPlay() override;
		virtual void Tick(float DeltaTime) override;
};
  • UCLASS()
    - 생성한 클래스를 언리얼 엔진의 리플렉션 시스템에서 인식하도록 하는 매크로
    - 언리얼 에디터에서 이 클래스를 블루프린트로 확장할 수 있게 하고, 에디터의 여러 기능과 연동하도록 함

  • AItem
    - 언리얼 엔진 C++에서는 클래스 이름에 접두사를 붙이는 컨벤션이 있음

    💡 언리얼 엔진 코드 컨벤션
    A - Actor 계열 / U - Object 계열 / F - 일반 구조체 / E - 열거형 등
    언리얼 엔진 코드 컨벤션 문서

  • GENERATED_BODY()
    - UCLASS()와 짝을 이루어, 엔진 리플렉션에 필요한 코드를 자동 생성해주는 매크로

  • BeginPlay()
    - 액터가 월드에 완전히 배치된 뒤, 게임이 플레이 상태로 시작할 때 한번 호출됨

  • Tick(float DeltaTime)
    - 매 프레임마다 자동으로 호출됨
    - 주로 매 프레임 단위의 업데이트가 필요한 로직을 이곳에 넣음


2. CPP 파일

#include "Item.h"

AItem::AItem()
{
		PrimaryActorTick.bCanEverTick = true;
}

void AItem::BeginPlay()
{
		Super::BeginPlay();
}

void AItem::Tick(float DeltaTime)
{
		Super::Tick(DeltaTime);
}
  • #include "Item.h"
    - .cpp 파일에서는 가장 먼저 짝이 되는 헤더파일을 포함해야 함
    ❗ 그렇지 않으면 언리얼의 자동 생성 매크로(리플렉션) 순서가 뒤섞여 컴파일 에러가 날 수 있음

< 컴포넌트 >

1. 정의

  • 언리얼 엔진에서 Actor가 어떤 역할을 하거나 특정 속성을 갖도록 만들어주는 부품 개념
  • 하나의 Actor가 여러 종류의 컴포넌트를 조합하여 다양한 기능을 구현할 수 있음

2. 종류

▸ 루트 컴포넌트 (Root Component)

  • 모든 Actor는 최상위 컴포넌트인 루트 컴포넌트(Root Component)를 가져야 함
  • 루트 컴포넌트는 액터의 트랜스폼(위치, 회전, 크기)을 정의하며, 모든 하위 컴포넌트가 이를 기준으로 동작함
  • 일반적으로, Scene Component를 루트로 설정하여 액터의 트랜스폼을 관리하고, 그 아래에 다양한 컴포넌트를 계층적으로 붙임

▸ 씬 컴포넌트 (Scene Component)

  • 모든 트랜스폼 속성을 가지는 기본 컴포넌트
  • 직접적인 시각적 출력(3d 모델, 빛 등)을 가지지 않지만, 다른 컴포넌트들의 계층적 트랜스폼을 정의하는 기준점 역할을 함
  • 씬 컴포넌트를 루트로 설정하면, 다른 시각적 컴포넌트를 아래에 Attach하여 관리할 수 있음

▸ 스태틱 메시 컴포넌트 (Static Mesh Component)

  • 애니메이션 없이 움직임이 없거나 단순 이동, 회전만 하는 고정된 3D모델을 표시하는 컴포넌트
  • 건물, 바위, 아이템, 환경 오브젝트 등 움직임이 없거나 단순한 오브젝트에 주로 사용됨
  • 3D 모델을 표현하고, 물리 충돌과 관련된 기능도 제공함
  • Static Mesh
    - 3D모델(정적 메시 데이터)을 정의
    - 모델 파일이며, 언리얼 엔진에서는 .uasset 파일로 관리됨
  • Material
    - 메시의 표면 시각적 속성을 정의
    - 색상, 질감, 반사율, 투명도 등의 속성을 설정할 수 있음
    - Static Mesh에는 여러 개의 머티리얼 슬롯이 있을 수 있음
    - 슬롯은 메시의 특정 부분에 다른 머티리얼을 적용할 수 있도록 함

3. 컴포넌트 연결

▸ Item.h

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

protected:
		USceneComponent* SceneRoot;
		UStaticMeshComponent* StaticMeshComp;
};

▸ Item.cpp

AItem::AItem()
{
	// 씬 컴포넌트 생성
	SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
    SetRootComponent(SceneRoot); // 씬 컴포넌트를 루트 컴포넌트로 설정
    
    // 스태틱메시 컴포넌트 생성
    StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
    StaticMeshComp->SetupAttachment(SceneRoot); // 스태틱메시 컴포넌트를 하위 컴포넌트로 설정
}
  • CreateDefaultSubobject<T>(TEXT(""))
    - 언리얼 엔진에서 컴포넌트를 생성하고 초기화할 때 사용하는 함수
    - 템플릿 타입 <T>로 생성할 컴포넌트의 유형을 지정
    - ""안에 컴포넌트의 식별 이름을 지정

    💡 TEXT() 매크로
    문자열을 유니코드로 처리하기 위한 것으로, 언리얼 엔진 코드 표준에서 권장함

  • SetRootComponent()
    - 매개변수로 들어온 컴포넌트를 루트 컴포넌트로 설정

  • SetupAttachment()
    - 매개변수로 들어온 컴포넌트에 함수를 호출한 컴포넌트를 부착함
    - 위에 예제에서는 StaticMeshComp가 SceneRoot에 부착되어, StaticMeshComp가 하위 컴포넌트가 됨

▸ 언리얼 에디터에서 확인

  • RootComponent는 설정하지 않아도 기본적으로 리플렉션 시스템에 등록되어 Details 창에서 확인할 수 있음 (StaticMeshComp는 보이지 않음)

4. Static Mesh 및 Material 설정

AItem::AItem()
{
	// 씬 컴포넌트 생성
    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);
    }
}
  • ConstructorHelpers::FObjectFinder<T>
    - 언리얼 엔진에서 특정 리소스를 경로 기반으로 로드하는 클래스

  • 리소스 경로

    - /Game 부분부터 입력하면 됨 (/Game은 언리얼 엔진에서 프로젝트의 Content를 나타냄

  • Succeeded()
    - 지정된 경로에서 리소스를 성공적으로 찾았는지 확인
    - 경로가 잘못되었거나 리소스 파일이 누락된 경우 실패하며, 이후 설정 함수가 호출되지 않음

  • SetStaticMesh(), SetMaterial()
    - Static Mesh를 StaticMeshComp에 설정
    - Materail을 StaticMeshComp의 특정 머티리얼 슬롯에 적용함

0개의 댓글