
먼저 언리얼에서 일반 C++파일을 생성한 뒤 데이터 구조를 제작하였다.
에디터에서 바로 헤더 파일만 생성해서 작성하는 사람도 있지만 비주얼은 헤더 파일부터가 인식이 안된다. 그냥 엔진에서 생성하였다.
(빨간 줄 신경안써도 된다. generated.h만 한시간 웹서핑 했는데 아몰랑 작성하고 돌리니까 그냥 굴러감.)
Item_Base 만들면서 cpp파일을 이쁘게 정리하려다가
에디터->빨간 지렁이 파티
엔진->모듈을 찾을 수가 없다고 에디터를 만지란다.
파일 이동하고 헤더파일 경로만 바꿔주면 된다고 생각했지만 아무래도 처음에 cpp파일을 만들때 public/private 파일 정리를 안해준 파일들을 그렇게 정리하려다가 꼬인 것 같다 그렇게 ProjectL_Mk.1은 세상을 떠났다...

아이템에 쓰일 데이터 구조를 헤더파일로 불러와 선언해주고 기본 함수를 구현하였다.

아이템의 복사본을 만드는 함수와 아이템의 수량을 수정하는 함수를 만들어 주었다.

라인트레이스를 이용해 폰이 바라보는 방향의 아이템이 있는지 확인한다.

아이템을 감지했을 경우와 감지하지 못했을 경우를 구현

아이템 감지 후 버튼을 눌렀을때 시작, 상호작용 중, 끝 상태를 구현
상호작용을 테스트하기 위한 테스트 액터 제작

테스트 액터를 생성하여 메쉬와 포커스, 상호작용 선언

아이템이 라인트레이스에 감지될 경우 표시해주기 위해 사용

포스트 프로세스에서 아이템을 표시할 커스텀 머터리얼을 선택하고 클릭하여 로그를 확인한다 키보드 E를 눌렀을때와 뗐을때 나오는 로그를 확인
에디터와 엔진에서 키 세팅 다 하고 캐릭터에서 입력 액션을 선택하는 것을 잊지 않아야한다.

BaseHUD를 만들고 이것을 기반으로 MainMenu 위젯과 InteractionWidget 위젯을 만들어 연결해줄 예정이다.

AddToViewport()에 숫자를 집어넣고 위젯 간의 우선순위를 정할 수 있다.

위의 함수들은 위젯을 숨기고 펼치는 역할을 한다.
UpdateInteractionWidget은 아래의 InteractionWidget에서 연결된다.

UserWidget에는 위젯과 마우스가 상호작용 가능한 Native~ 함수들이 존재한다.
마우스 드래그나 드롭 클릭시에 사용 가능한 함수들이다.
NativeOnInitialized() = 위젯이 생성될때 호출된다.
NativeConstruct() = AddToViewport시 호출된다.
NativeDestruct() = RemoveFromParent(RemoveFromViewport) 시 호출된다.
cpp파일에서 Super가 계속 UUserWidget에서 상속받은 것을 인지하지 못하고 그의 윗 부모인 UWidget에는 멤버가 존재하지 않는다는 말만 반복하며 오류가 떴다.
가상함수를 가져와 오버라이드 하는 경우 cpp파일의 함수에서 UInteractionWidget을 UWidget으로 바꿔서 빌드해준 뒤
UInteractionWidget로 다시 바꾸면 사라진다.
엄청난 웹서핑으로 나의 시간도 사라졌다.
그냥 빌드해도 상관없다...

UpdateWidget은 상호작용할 액터의 상호작용 데이터에 접근하여 데이터 타입을 체크해 관련 위젯을 띄울수 있도록 switch 함수를 사용하였다.

InteractionWidget을 상속받아 블루프린트에서 위젯을 제작했다.
아이템이 감지되면 아이템의 정보를 띄운다.


메인 메뉴 위젯은 다음에 등장할 InventoryPanel을 탑재할 위젯이다.
후에 드래그 기능을 추가한다.
인벤토리에 넣을 수 있는 액터 제작

픽업과 드롭 액터가 포커스에 잡혔는지 알리기 위해 비긴과 엔드 포커스 함수 선언

빈 Mesh와 ItemDataTable 그리고 테이블과 상호작용을 위한 ID, Item_Base 기반의 ItemReference, 수량, 데이터를 선언한다.

엔진에서 데이터 테이블에 설정한 각 아이템 별 아이디를 사용할 Pickup의 DesiredItemID에 입력해 ItemReference를 생성해준다.

아이템을 드롭했을때 수량과 무게 그리고 해당 메쉬를 입힌다.
아이템을 픽업, 드롭했을때 각각의 상호작용 데이터를 업데이트한다.

아이템이 픽업 당할 경우 픽업 아이템의 처리를 진행한다.

액터가 이미 월드에 소환되어 있는 상황에 에디터에서 액터의 내부 정보를 수월하게 변경하기 위해 PostEditChangeProperty함수를 사용한다.
GET_MEMBER_NAME_CHECKED를 같이 사용하여 에디터에서 ID가 바뀌면 해당 아이디의 정보와 메쉬로 바뀐다.

헤더파일에서 선언 시 #if WITH_EDITOR를 사용해 에디터 모드에서만 작동하게 만들어 런타임 중에는 사용하지 않아 최적화가 가능하다.
대망의 인벤토리를 이제야 다룬다.

아이템이 들어갔는지 알려주기 위한 열거형

아이템 추가 결과를 알려주는 구조체

아이템 추가, 탐색, 삭제 분할을 위한 함수들과 getter, setter를 선언

인벤토리의 무게나 슬롯 용량을 다루는 변수, 인벤토리 배열 변수, 쌓을 수 있는 아이템과 없는 아이템을 나눠서 처리하는 함수, 무게나 슬롯 용량을 계산하는 함수, 아이템을 추가하는 함수를 선언한다.

탐색에 해당하는 함수들의 정의 부분

계산과 삭제, 분할에 대한 함수들이다.

쌓을 수 없는 아이템의 처리 함수
// 쌓을 수 있는 아이템의 처리 함수

새로운 아이템의 추가 함수
아이템이 이미 복사되거나 월드에 존해했던 아이템인 경우 모든 아이템이 포인터로 다뤄지기 때문에 다른 아이템이지만 주소가 중복되어 있는 경우가 있을 수 있다.
UItem_Base에 bIsCopy와 bIsPickup을 추가해주어 위의 경우들을 검사한다.


InventoryPanel은 인벤토리에 들어있는 아이템을 랩박스인 InventoryPanel에 띄우고 무게와 아이템 슬롯의 수치를 알려준다.
패널에 연결 시켜 줄 슬롯은 인벤토리 작업 후 진행한다.
위와 같이 UPROPERTY에서 meta=(BindWidget)을 선언해준 경우 해당 항목을 연결시켜 주지 않으면 컴파일부터가 진행되지 않는다. 그 상태로 게임을 실행하면 크래쉬가 나면서 엔진이 꺼지기 때문에 주의해야 한다.

NativeOnInitialized에서 현재 플레이 캐릭터의 인벤토리를 가져와 델리게이트 설정해주었던 OnInventoryUpdated를 InventoryPanel의 RefreshInventory에 부착해준다.
SetInfoText는 패널에서 무게와 슬롯의 수치를 계산해 알려주는 함수이다.
RefreshInventory에서 인벤토리의 비주얼적인 업데이트가 진행된다고 볼 수 있는데 인벤토리와 슬롯이 존재하는지 확인하고 인벤토리 배열에서 아이템 정보를 가져와 아이템 슬롯에게 넘겨주고 SetInfoText로 텍스트 부분을 업데이트한다.

아이템 슬롯이 드래그 될 경우 마우스를 따라갈 슬롯의 축소판인 DragItemVisual이다.
변수 선언만 해준 뒤 초기화 작업은 InventoryItemSlot에서 진행한다.

아이템 슬롯은 아이템이 마우스로 드래그 될 경우 작게 표현될 DragItemVisualClass와 아이템에 마우스를 올리면 아이템의 정보를 알려줄 ToolTipClass를 TSubclassOf로 받는다.
그리고 아이템을 슬롯을 구성할 보더, 아이콘, 수량 텍스트를 바인드 위젯해준다.
그 아래는 아이콘에 대한 마우스 활동을 감지할 Native 함수들이다.

NativeOnInitialized를 통해 슬롯에 마우스가 올라갈 경우 아이템의 정보를 담은 툴팁이 생성된다.
아이템 보더에는 아이템의 등급에 따라 테두리의 색깔이 바뀌도록 만들었다.
아이템이 bIsStackable인 경우에만 수량을 표시한다.

마우스를 클릭한 경우 드래그 감지를 준비한다.
슬롯이 마우스에 의해 드래그되면 해당 슬롯의 정보로 DragVisual 위젯을 만든다.
ItemDragDropOperation은 UDragDropOperation을 상속받은 클래스로 아이템과 인벤토리만 선언 해주었다.
DragItemOperation을 생성하여 아이템과 인벤토리 비주얼 정보를 답고 Pivot은 아이콘이 잘 보이도록 마우스 왼쪽 위로 설정하였다.

캐릭터에 DropItem 함수를 추가하여 SpawnParams와 캐릭터의 위치를 토대로 드롭한 아이템이 스폰되도록 만들었다.

MainMenu의 NativeOnDrop에서 유효성 검사를 실행한 뒤 캐릭터의 DropItem 함수를 호출한다.


아이템 툴팁은 아이템의 정보들을 다 바인드 위젯해주고

아이템의 타입이나 등급에 따라 각기 다른 정보를 보여주도록 만들었다.
This article provides a detailed overview of developing an inventory system in Unreal Engine 5, covering data structures, object interaction handling, and user interface creation. It’s a great example of building a customized system tailored to specific needs.However, for most businesses, especially those in e-commerce or managing large warehouses, developing a custom system can be resource-intensive. In such cases, it’s worth considering ready-made solutions that offer robust inventory management capabilities.I recommend checking out the inventory warehouse management system options that provide real-time stock tracking, ERP integration, and process automation. These features help reduce errors, improve efficiency, and lower inventory management costs.