Unreal

C++을 사용한 언리얼엔진 인벤토리 시스템 Part.1

story98138 2026. 3. 9. 16:33

 

1.프로젝트 만들기

*식자는 프로젝트 이름을 설정할 때 오타를 내서 IntentorySystemCpp로 만들어버렸지만 나중에 알아버려서 이는 굳이 수정하지 않겠다.

사용할 언리얼 엔진 버전을 실행하고 3인칭 템플릿, C++으로 프로젝트를 생성한다.

 

2. C++ 블루프린트 클래스 생성

먼저 Add C++ Class에서 Actor Component를 생성한다.(InventoryComponent)

 

비어있는 C++ 클래스도 하나 생성한다.(InventoryDataStructs)

 

3개의 C++ Class의 User Widget을 생성한다.

 

3. 구조체 선언하기

이제 비주얼 스튜디오를 열면 메세지 창이 하나 떠있을 것이다.

당황하지 말고 Reload All을 클릭한다.

 

InventoryDataStructs.h 헤더파일로 가서 이와같이 작성한다.

 

  • InventoryDataStructs.h에서 FLines 라는 구조체를 선언하고 나중에 이어서 작성하기 위해 FLines() { }; 생성자는 비워둔다.

  • TArray<FVector2D> XLines; & TArray<FVector2D> YLines;
    - XLines와 YLines는 인벤토리 그리드를 그릴 때 필요한 가로선들과 세로선들의 2D 좌표값을 여러 개 담아두는 바구니 역할을 한다.

 

InventoryWidget.h 헤더파일로 가서 이와같이 작성한다.

 

 

  • class UCanvasPanel; / class UBorder; / class UBackgroundBlur;
    - 전방 선언(Forward Declaration) "이런 UI 클래스들이 존재하니까 나중에 쓸 거다"라고 컴파일러에게 미리 귀띔해 주는 역할이다. 헤더 파일에 굳이 무거운 #include를 다 적지 않아도 되어 컴파일 속도를 높여준다.
  • class INTENTORYSYSTEMCPP_API UInventoryWidget : public UUserWidget
    - UUserWidget이라는 언리얼 엔진의 기본 UI 위젯 클래스를 상속받아, 나만의 기능이 담긴 UInventoryWidget을 선언한다.

  • UPROPERTY(VisibleAnywhere, meta = (BindWidget), Category = "UI")
    - 이 파일에서 가장 중요한 핵심 기능.
    - meta = (BindWidget)은 언리얼 에디터(UMG)에서 생성한 동일한 이름의 UI 요소와 아래에 선언할 C++ 변수를 **강제로 연결(Bind)**하라는 명령이다.
    - 만약 블루프린트 위젯에 아래 변수명(Canvas, BackgroundBorder, Blur)과 똑같은 이름의 위젯 요소가 없다면 컴파일 시 에러가 발생한다.

  • UCanvasPanel* Canvas; / UBorder* BackgroundBorder; / UBackgroundBlur* Blur;
    - 앞선 BindWidget 매크로에 의해 실제 UI 요소들과 연결될 포인터 변수들.
    - 인벤토리의 전체 바탕을 담당하는 캔버스(Canvas), 외곽선 테두리(BackgroundBorder), 배경을 반투명하게 흐려주는 블러 효과(Blur) 위젯을 C++에서 조작할 수 있게 담아두는 바구니 역할을 한다.

  • virtual void NativeConstruct() override;
    - 블루프린트의 Event Construct 노드와 완벽히 같은 역할을 하는 C++ 함수. 이 인벤토리 위젯이 화면에 처음 생성될 때 딱 한 번 실행되며, 초기 셋팅이나 필요한 데이터를 불러올 때 사용한다.

 

InventoryWidget.cpp 소스코드로 가서 이와같이 작성한다.

 

  • void UInventoryWidget::NativeConstruct()
    - 헤더 파일에서 선언했던 NativeConstruct 함수의 실제 실행 내용을 적는 블록이다.

  • Super::NativeConstruct();
    - Super는 내 클래스의 부모 클래스(여기서는 언리얼의 기본 위젯인 UUserWidget)를 의미한다.

 

InventoryGridWidget.h 헤더파일로 가서 이와같이 작성한다.

 

  • UI 요소 바인딩 (BindWidget): 언리얼 에디터에서 디자인할 바탕 캔버스(Canvas), 테두리(GridBorder), 그리고 실제 아이템과 격자 선이 그려질 핵심 도화지(GridCanvasPanel)를 C++ 코드와 연결한다.

  • 데이터 구조체 가져오기: 상단에 #include "InventoryDataStructs.h"를 추가한 것으로 보아, 맨 처음 만들었던 가로/세로선 좌표 데이터(FLines)를 바로 이 위젯에서 불러와서 사용할 예정이다.

  • 기능의 모듈화 (분리): 전체 인벤토리 창(가방)과 아이템 격자(그리드)를 따로 분리해 두면, 나중에 상자(Chest)를 열거나 상점 거래 창을 만들 때 이 격자 부분만 똑 떼어서 재사용하기가 훨씬 쉬워진다.

 

언리얼 에디터로 돌아와서 하단의 컴파일 버튼을 눌러 컴파일 후 파일 검사

 

여기에서 에러가 난다면 "InventoryDataStructs.h"에서 
#include "InventoryDataStructs.generated.h"  를 추가하면 에러가 사라질 것이다.

 

4. 내 캐릭터에 적용하기

내 프로젝트의 .Build.cs 파일을 열어서 아래와 같이 "UMG" 를 추가한다.
UMG: Unreal Motion Graphics의 약자

 

캐릭터 해더파일을 열어서 protected: 부분을 아래와 같이 작성한다.
캐릭터,cpp 파일에 추가 작성을 위해서 
void ToggleInventory();virtual void BeginPlay() override;  를 꼭 선언해줘야한다.  

 

인벤토리 액션 부분도 작성해준다.

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
UInputAction* InventoryAction;

 

 

이제 헤더파일에서 선언한 것을 캐릭터.cpp파일에서 함수를 만들어줄 차례다.

 

BeginPlay 함수 추가

 

ToggleInventory 함수 추가

 

이제 솔루션 컴파일을 해서 에러가 없는지 확인한다.

에러가 난다면 에러가 난 파일에 
#include "Kismet/GameplayStatics.h"
#include "Blueprint/UserWidget.h"
이와 같은 도구를 추가해주면 될 것 이다.

 

5. 캐릭터 블루프린트 설정

마지막으로 캐릭터 블루프린트에서 두 가지의 설정을 할 건데 그 전에 인벤토리를 열 Key를 지정해주어야한다.
Input-> Actions 폴더에 들어가서 Input Actions 클래스를 만들고 밸류 타입을 디지털로 설정한다. (이름은 IA_Inventory)
캐릭터가 사용중인 매핑컨텍스트를 열어서 만든 Input Actions 클래스에  "I"키를 매핑한다.

 

이제 캐릭터 블루프린트 설정을 할 차례이다.

 

  • 캐릭터 블루프린트의 디테일 창에서 UI를 검색 후 Inventory Widget Class 를 BPW_Inventory로 변경해준다.
  • 똑같이 캐릭터 블루프린트의 디테일 창에서 Input을 검색 후 Inventory Action을 IA_Inventory로 설정한다.

컴파일 후 세이브 ***

 

6. 테스트

플레이를 했을 때, I 키를 눌러 인벤토리 위젯이 잘 작동하는지 확인한다.

 

 

여기까지 C++을 사용한 언리얼엔진 인벤토리 시스템 Part.1이다.

다음엔 인벤토리 슬롯에 타일라인을 넣어보겠다.