언리얼엔진
언리얼엔진 Composition 사용법
silbaram
2025. 4. 7. 19:30
728x90
컴포지션(Composition)은 상속(Inheritance) 대신 여러 개의 작은 모듈(컴포넌트)을 조합하여 객체의 기능을 확장하는 방법입니다. 언리얼 엔진에서는 Actor Component를 사용하여 액터에 다양한 기능(예: 체력, 무기, 인터랙션 등)을 부여하는 방식으로 컴포지션을 구현합니다.
컴포지션의 장점은 다음과 같습니다:
- 유연성: 각 기능을 독립된 컴포넌트로 만들어 여러 액터에서 재사용할 수 있습니다.
- 유지보수: 기능이 분리되어 있어 코드 수정 및 확장이 쉽습니다.
- 의존성 감소: 상속 계층이 깊어지지 않아 클래스 간 의존성이 줄어듭니다.
아래 예제는 체력(Health) 기능을 가진 컴포넌트를 만들어, 이를 액터에 추가하는 방식을 보여줍니다.
1. UHealthComponent (체력 컴포넌트) 만들기
HealthComponent.h
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "HealthComponent.generated.h"
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class MYPROJECT_API UHealthComponent : public UActorComponent
{
GENERATED_BODY()
public:
UHealthComponent();
protected:
virtual void BeginPlay() override;
public:
// 최대 체력
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health")
float MaxHealth;
// 현재 체력
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Health")
float CurrentHealth;
// 데미지를 입는 함수
UFUNCTION(BlueprintCallable, Category = "Health")
void TakeDamage(float DamageAmount);
};
HealthComponent.cpp
#include "HealthComponent.h"
UHealthComponent::UHealthComponent()
{
PrimaryComponentTick.bCanEverTick = false;
MaxHealth = 100.f;
CurrentHealth = MaxHealth;
}
void UHealthComponent::BeginPlay()
{
Super::BeginPlay();
}
void UHealthComponent::TakeDamage(float DamageAmount)
{
CurrentHealth = FMath::Clamp(CurrentHealth - DamageAmount, 0.f, MaxHealth);
UE_LOG(LogTemp, Log, TEXT("Damage Taken: %f, Current Health: %f"), DamageAmount, CurrentHealth);
}
2. AMyActor에 UHealthComponent 추가하기
컴포지션 방식으로 AMyActor에 체력 기능을 추가하려면, AMyActor의 멤버 변수로 UHealthComponent를 선언하고 생성자에서 생성합니다.
MyActor.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "HealthComponent.h" // 체력 컴포넌트 포함
#include "MyActor.generated.h"
UCLASS()
class MYPROJECT_API AMyActor : public AActor
{
GENERATED_BODY()
public:
AMyActor();
protected:
virtual void BeginPlay() override;
public:
// 컴포지션: 체력 기능을 담당하는 컴포넌트
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UHealthComponent* HealthComp;
};
MyActor.cpp
#include "MyActor.h"
AMyActor::AMyActor()
{
PrimaryActorTick.bCanEverTick = false;
// 생성자에서 HealthComponent 생성 및 기본 서브오브젝트로 등록
HealthComp = CreateDefaultSubobject<UHealthComponent>(TEXT("HealthComponent"));
}
void AMyActor::BeginPlay()
{
Super::BeginPlay();
// 예시: 액터 시작 시 체력 컴포넌트에 데미지 적용
if (HealthComp)
{
HealthComp->TakeDamage(25.f);
}
}
3. 결론
이 예제에서는 컴포지션을 사용하여 AMyActor가 체력 관련 기능을 직접 구현하지 않고, 별도의 UHealthComponent를 포함함으로써 기능을 확장했습니다. 이를 통해 여러 액터에 동일한 기능을 손쉽게 재사용할 수 있으며, 각 기능이 독립적이므로 코드 유지보수와 확장이 더욱 용이해집니다.
728x90