게임 개발/학습 일지

언리얼 C++ - 인터페이스 기반 아이템 클래스 설계하기

이개 2026. 4. 21. 08:55

언리얼에서의 인터페이스

언리얼에서는 UInterface라는 클래스를 지원해준다. 

  • 인터페이스에 함수 원형들만 정의해주고, 아이템 클래스들이 이 인터페이스를 구현한다.

C++ 클래스 추가하기에서 Unreal Interface 선택
ItemInterface 생성

 

언리얼 인터페이스의 경우, 클래스가 두 개 생성되는 것을 볼 수 있다.

  • 위에 있는 UInterface 인터페이스는 리플렉션을 위한 인터페이스라서 수정할 필요가 없다.
    • MinimalAPI는 현재 모듈 내에서만 접근 가능하도록 제한한다.
  • 아래 있는 인터페이스는 직접 구현하는 인터페이스다.
    • 순수 가상함수를 여기다 구현한다.

cpp파일은 내버려두면 된다. 언리얼 리플렉션 시스템에서 빌드를 할 때 헤더와 구현 파일을 쌍으로 확인하기 때문에 cpp파일을 삭제해버린다면 불안정하게 된다.

 

 

설계는 확장할 부분까지 고려해서 구현한다.

 

 

 

BaseItem에서는 IItemInterface를 상속받아 함수를 구현해놓는다.

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ItemInterface.h" // 아이템 인터페이스  
#include "BaseItem.generated.h"

UCLASS()
class SPARTAPROJECT_API ABaseItem : public AActor, public IItemInterface // 
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ABaseItem();

protected:
	virtual void OnItemOverlap(AActor* OverlapActor) override; // 캐릭터, 몬스터 등 여러 경우를 생각해서 캐스팅할 수 있도록 AActor 클래스를 받는다.
	virtual void OnItemEndOverlap(AActor* OverlapActor) override;
	virtual void ActivateItem(AActor* Activator) override;
	virtual FName GetItemType() const override;// 아이템 구분할 때 사용. FName은 FString보다 속도도 빠르고 메모리 절약이 된다. 그래서 타입같은 경우는 FName을 쓴다.

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
	FName ItemType;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

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


#include "BaseItem.h"

// Sets default values
ABaseItem::ABaseItem()
{
 	// 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;

}

void ABaseItem::OnItemOverlap(AActor* OverlapActor)
{

}

void ABaseItem::OnItemEndOverlap(AActor* OverlapActor)
{
}

void ABaseItem::ActivateItem(AActor* Activator)
{
}

FName ABaseItem::GetItemType() const
{
	return ItemType;
}



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

}

 

 

이제 코인 아이템을 만든다.

All Classes에서 방금 만든 BaseItem을 찾아 상속받는다.
파일명은 CoinItem

 

생성자만 만들어주고 이를 또 상속받는다.

 

CoinItem을 상속받은 BigCoinItem을 만든다.

아이템 타입은 부모 클래스가 아닌 말단 자식 클래스에서 만들어준다. 

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

#pragma once

#include "CoreMinimal.h"
#include "CoinItem.h"
#include "BigCoinItem.generated.h"

/**
 * 
 */
UCLASS()
class SPARTAPROJECT_API ABigCoinItem : public ACoinItem
{
	GENERATED_BODY()
	
	ABigCoinItem();

	virtual void ActivateItem(AActor* Activator) override;
};
// Fill out your copyright notice in the Description page of Project Settings.


#include "BigCoinItem.h"

ABigCoinItem::ABigCoinItem()
{
	PointValue = 50;
	ItemType = "BigCoin";
}

void ABigCoinItem::ActivateItem(AActor* Activator)
{
	DestroyItem();
}

 

CoinItem을 상속받은 SmallCoinItem을 만든다.

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

#pragma once

#include "CoreMinimal.h"
#include "CoinItem.h"
#include "SmallCoinItem.generated.h"

/**
 * 
 */
UCLASS()
class SPARTAPROJECT_API ASmallCoinItem : public ACoinItem
{
	GENERATED_BODY()

public:
	ASmallCoinItem();
	virtual void ActivateItem(AActor* Activator) override;
	
};
// Fill out your copyright notice in the Description page of Project Settings.


#include "SmallCoinItem.h"

ASmallCoinItem::ASmallCoinItem()
{
	PointValue = 10;
	ItemType = "SmallCoin";
}

void ASmallCoinItem::ActivateItem(AActor* Activator)
{
	DestroyItem();
}

BaseItem을 상속받아 힐링 아이템을 만든다.

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

#pragma once

#include "CoreMinimal.h"
#include "BaseItem.h"
#include "HealingItem.generated.h"

/**
 * 
 */
UCLASS()
class SPARTAPROJECT_API AHealingItem : public ABaseItem
{
	GENERATED_BODY()

public:
	AHealingItem();
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
	float HealAmount;
	virtual void ActivateItem(AActor* Activator) override;
	
};
// Fill out your copyright notice in the Description page of Project Settings.


#include "HealingItem.h"

AHealingItem::AHealingItem()
{
	HealAmount = 20.0f;
	ItemType = "Healing";
}

void AHealingItem::ActivateItem(AActor* Activator)
{
	DestroyItem();
}

역시 BaseItem을 상속받아 MineItem을 만든다

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

#pragma once

#include "CoreMinimal.h"
#include "BaseItem.h"
#include "MineItem.generated.h"

/**
 * 
 */
UCLASS()
class SPARTAPROJECT_API AMineItem : public ABaseItem
{
	GENERATED_BODY()

public:
	AMineItem();

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
	float ExplosionDelay; // 폭발 지연시간
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
	float ExplosionRadius; // 폭발 반경
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
	float ExplosionDamage; // 폭발 대미지


	virtual void ActivateItem(AActor* Activator) override;
	
};
// Fill out your copyright notice in the Description page of Project Settings.


#include "MineItem.h"

AMineItem::AMineItem()
{
	ExplosionDelay = 5.0f;
	ExplosionRadius = 300.0f;
	ExplosionDamage = 35.0f;
	ItemType = "Mine";
}

void AMineItem::ActivateItem(AActor* Activator)
{
	DestroyItem();
}

 

 

반복작업이므로 적당히 해주면 된다.