카테고리 없음

언리얼 C++ - Actor 클래스에 컴포넌트 추가하기

이개 2026. 4. 11. 17:51

언리얼 엔진 C++에서는 클래스 이름에 접두사를 붙이는 접두사 규칙이 있다.

  • A (Actor 계열)
  • U (Object 계열)
  • F (구조체)
  • T (템플릿)
  • E (열거형)
// ❌ NewObject - 런타임 생성 (생성자에서 사용 안 됨)
UMyComponent* Comp = NewObject<UMyComponent>();

// ✅ CreateDefaultSubobject - 생성자에서만 사용
UMyComponent* Comp = CreateDefaultSubobject<UMyComponent>(TEXT("MyComp"));

기본 Actor 상속으로 만들었던 Item.h 파일로 보는 구조

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

#pragma once

#include "CoreMinimal.h" // 언리얼 엔진의 기본 타입
#include "GameFramework/Actor.h" // 액터에 대한 정보를 가지고 있는 헤더파일
#include "Item.generated.h" // 리플렉션 시스템에 관련한 헤더 파일

UCLASS() // 리플렉션 시스템에 등록해주는 키워드

// SPARTAPROJECT_API는 이 클래스를 모듈 밖으로 내보내게 해주는 일종의 매크로다.
// 빌드할 때 중요하다.
// 보통 API 앞에 이름을 붙여 쓴다.
class SPARTAPROJECT_API AItem : public AActor // A 접두어는 Actor계열이라는 의미이다. Object는 U, 구조체는 F, Enum은 E
{
	GENERATED_BODY() // UCLASS와 같은 역할의 매크로
    // 헤더 생성기(UHT)가 리플렉션 코드 자동 생성
	
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;
	
};
// Fill out your copyright notice in the Description page of Project Settings.


#include "Item.h"

// Sets default values
AItem::AItem()
{
 	// 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; // Tick 함수 관련된 선언

}

// Called when the game starts or when spawned
void AItem::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AItem::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

 

  • UCLASS(Blueprintable)           // 블루프린트로 상속 가능
  • UCLASS(BlueprintType)           // 블루프린트 변수 타입으로 사용 가능
  • UCLASS(Abstract)                // 직접 인스턴스 생성 불가
  • UCLASS(Notplaceable)            // 에디터에서 드래그해서 놓기 불가
  • UCLASS(EditInlineNew)           // 에디터에서 인라인 생성 가능

 

UCLASS()
class AMyCharacter : public AActor
{
    GENERATED_BODY()

public:
    // 기본
    UPROPERTY()
    int32 Health;

    // 에디터에서 편집 가능
    UPROPERTY(EditAnywhere)
    float Speed;

    // 블루프린트에서 접근 가능
    UPROPERTY(BlueprintReadWrite)
    FString CharacterName;

    // 저장됨
    UPROPERTY(SaveGame)
    int32 Score;
};
  • UPROPERTY(EditAnywhere)         // 에디터 어디서나 편집
  • UPROPERTY(EditDefaultsOnly)     // CDO(Class Default Object)에서만 편집
  • UPROPERTY(EditInstanceOnly)     // 인스턴스에서만 편집
  • UPROPERTY(VisibleAnywhere)      // 에디터에서 보임 (수정 불가)
  • UPROPERTY(BlueprintReadOnly)    // 블루프린트에서 읽기만
  • UPROPERTY(BlueprintReadWrite)   // 블루프린트에서 읽고쓰기
  • UPROPERTY(Category = "Stats")   // 에디터 카테고리 분류

 

Item에 스태틱 메시와 머티리얼 적용하기

// Fill out your copyright notice in the Description page of Project Settings.
  
#include "Item.h"

// Sets default values
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는 반드시 클래스의 생성자(Constructor) 안에서만 호출되어야 함.

void AMyActor::BeginPlay() 에서는 사용 불가.

 

머티리얼과 머티리얼 인스턴스 로드

머티리얼 인스턴스를 강의 내용대로 스태틱 메시에 적용하려고 하니, 오류가 뜨면서 적용되지 않았다.

C++에서 두 리소스를 로드할 때 사용하는 클래스 타입이 달라서였다.

  • 머티리얼 (UMaterial):
    • 정의: 쉐이더의 '원본 설계도'.
    • 코드 로드: ConstructorHelpers::FObjectFinder<UMaterial>를 주로 사용.
  • 머티리얼 인스턴스 (UMaterialInstanceConstant):
    • 정의: 원본 머티리얼을 부모로 삼고, 수치(파라미터)만 바꾼 '사본'입니다.
    • 코드 로드: ConstructorHelpers::FObjectFinder<UMaterialInstanceConstant>를 사용.

주의: 만약 코드에서 인스턴스를 불러오는데 UMaterial 타입으로 받으려고 하면 캐스팅 오류가 발생하거나 로드에 실패할 수 있음.

머티리얼 인스턴스를 받는 방법
 - UMaterialInterface 사용

// Fill out your copyright notice in the Description page of Project Settings.
  
#include "Item.h"

// Sets default values
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<UMaterialInterface> MaterialAsset(TEXT("/Game/Resources/Materials/M_Metal_Steel.M_Metal_Steel"));
		if (MaterialAsset.Succeeded())
		{
			StaticMeshComp->SetMaterial(0, MaterialAsset.Object);
		}
}