Tarkov-like Inventory Tutorial (3/4)

Brann Goldbeard·2025년 9월 25일

인벤토리 시스템

목록 보기
3/4

지난 시간에 이어 UMG 작업을 이어 할 예정이다.

아직 Inventory Widget에 이미지가 출력되고 있지 않기 때문에 해당 부분을 진행해보도록 하자.

WBP_InventoryGrid 내부에서 Refresh 함수를 생성하도록 하자.
해당 함수는 인벤토리 위젯에 아이템이 생성 및 이동 될 때 호출될 함수이다.

Refresh 함수 내에서 Grid Panel을 초기화 해주고, Inventory Component 내에 존재하는 ItemObject(실제 아이템 정보)를 검색하여 탐색한다.

이를 위해서 InventoryComponent로 이동하여 GetAllItems 함수를 생성하도록 하자.


  • 해당 GetAllItems 함수는 인벤토리 배열의 모든 슬롯을 순회하여, 실제 데이터(Null이 아닌)를 가진 유효한 아이템 객체만 중복 없이 필터링하여 하나의 목록을 만들어 AllItems(Local)을 반환하는 역할을 한다.

다시 WBP_InventoryGrid로 돌아와서,


해당 아이템 배열을 순회하며 화면에 WBP_Item 출력시켜주도록 한다.

출력시킬 WBP_Item에 대한 작업을 해보도록 하자.

Canvas Panel에 변경될 아이콘의 SizeBox_Background, Border_Background를 만들어주었다.
마지막으로 아이템의 Image를 Canvas Panel에 추가해준다.

인벤토리 내 추가될 WBP_Item을 만들어주고 이벤트 그래프로 돌아가서 아이템 정보와 Tile Size를 전달받아오도록 한다.

  • WBP_Item에 추가된 변수들

마찬가지로 Initialize 이벤트를 호출해서 Delay 노드를 추가하고 Refresh 이벤트를 연결해준다.

WBP_Item에서 동작할 Refresh Event는 인벤토리가 새로 그려질 때 ItemObject로 부터 2차원 정보를 가져와
TileSize에 맞게 실제 인벤토리 위젯에 출력해주고 Size를 지정해줄 예정이다.

  • 해당 커스텀 이벤트에서 아이템의 정보를 실제 위젯에 그려주고 있다.

  • WBP_Item의 Image의 Brush 속성에 함수를 Binding 해준다. (GetIconImage)
    해당 함수에서는 아이템 정보에 할당해준 이미지를 가져올 예정이다.

  • 다음과 같이 ItemObject로 부터 아이콘을 가져와 Make Slate Brush 노드를 통해 value를 전달해준다.
    하지만 아직 ImageObject에 Icon Image를 전달해주는 함수를 만들지 않았으니 ItemObject 클래스로 이동해서 아이콘을 전달해주는 함수를 만들도록 하자.

  • ItemObject에서 GetIcon 함수를 만들었다. 위 함수는 Rotated return 값에 따라 일반 이미지와 회전 이미지를 전달한다.

마지막으로 WBP_Item에 OnRemoved 이벤트 디스패처를 생성하고 WBP_InventoryGrid로 넘어가도록 하자.
(파라미터 입력값에 ItemObject를 정의해주었다.)
이 이벤트 디스패처는 아이템이 인벤토리로부터 지워질 때(혹은 드래그앤드롭) 호출되는 이벤트가 될 예정이다.

  • WBP_InventoryGrid에서 다음과 같이 OnItemRemoved(Custom event) 함수를 만들어주고

  • 해당 함수에서는 단순히 Inventory Component에서 아이템을 지우는 함수를 호출해주도록 한다.
    당연히 우린 해당하는 함수를 만든 적이 없으므로, Inventory Component로 이동해서 Remove Item 함수를 만들어주자.

  • 입력된 아이템이 유효하면, 인벤토리를 순회해서 입력된 아이템과 비교하며 참일 경우 아이템 인벤토리에 추가하고 IsDirty Boolean을 참으로 바꿔준다.

WBP_InventoryGrid로 이동해서 Refresh 함수를 마무리해보자.

Removed 함수가 호출되고 Grid Canvas Panel Add Child를 통해 해당 이미지를 그리드 패널에 추가하고,
CanvasPanelSlot casting을 통해 성공할 경우 SetAutoSize와 Set Position 노드를 이용해 크기와 위치를 지정해준다.
Set Position에 들어가는 S_Tile은 GetAllitems의 반환값에서 For each loop로 순회하는 Map value에서 가져와 곱해서 할당해주면 된다.

드디어 기나긴 Refresh 함수를 완성했다.

이제 WBP_InventoryGrid - Initialize 함수로 이동해 Refresh를 연결해주고,

Inventory Component에서 새로운 이벤트 디스패처를 생성해준다.

  • 위의 OnInventoryChanged 이벤트 디스패처를 생성하고 Tick 이벤트에 IsDirty가 참이면, IsDirty를 false로 바꿔주고 해당 이벤트 디스패처가 호출되게끔 해주었다.
    이는 매 프레임마다 IsDirty 여부를 확인하고 참일 경우 해당 이벤트를 호출하게 된다.
    (IsDirty 변수는 바로 직전에 작업했던 RemoveItem 함수 내에 있다.)

다시 WBP_InventoryGrid - Initialize로 이동해서 만든 이벤트 디스패처를 연결해주면서 마무리해주면,

아이템을 줍게되면 인벤토리에 제대로 그려진다. 하지만 인벤토리를 열면 마우스 포인터가 보여서 원하는 대로 동작하지 않을텐데
이는 다음 시간에 고치도록 하겠다.

또한 마지막 튜토리얼 이전에 테스트 환경을 위해 위처럼 다양한(칼, 수류탄) 아이템을 만들어 원하는 사이즈를 지정해 AK-47과 같이 아이템을 추가해보길 바란다.

0개의 댓글