장비 데이터 테이블 추가
먼저 무기나 장비로 취급할 아이템을 판별하기 위해 FKOEquipmentRow를 추가했다.
USTRUCT(BlueprintType)
struct KARON_API FKOEquipmentRow : public FTableRowBase
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Equipment")
FGameplayTag ItemTag;
};
프로젝트에서 GAS를 사용하고 있기 때문에, 능력치 처리는 나중에 GameplayEffect나 Ability 쪽에서 담당할 예정이기 때문에 현재 단계에서는 장비의 공격력, 방어력, 장착 소켓 같은 정보는 넣지 않았다.
장비 테이블은 단순히 ItemTag를 가진 아이템은 장비로 취급한다.
장비는 일반 아이템이면서, 동시에 장비로 판별된다.
Equipment 데이터 로드
장비 테이블을 사용하기 위해 KOLoadSubsystem에 Equipment 테이블을 추가했다.
IndexTableRowsByName<FKOEquipmentRow>(
Settings->EquipmentTables,
EquipmentCache,
TEXT("Equipment")
);
그리고 장비 여부를 빠르게 확인하기 위해 EquipmentTagToId 역인덱스를 만들었다.
EquipmentTagToId.Add(Row->ItemTag, Pair.Key);
특정 아이템의 ItemTag가 DT_Equipment에 등록되어 있는지 확인할 수 있다.
무기 장비 판별
UI에서 매번 LoadSubsystem을 직접 가져와서 사용하면 코드가 지저분해지기 때문에, 장비 판별 로직은 UKOItemLibrary로 분리했다.
- IsEquipmentItem() : 해당 아이템이 장비 테이블에 등록되어 있는지 확인한다.
- IsWeaponEquipmentItem()
1. DT_Item에 존재하는 아이템인가?
2. 해당 ItemTag가 DT_Equipment에 등록되어 있는가?
3. Item.Category.Weapon 카테고리를 가지고 있는가?
즉, 무기 슬롯에는 단순히 장비 테이블에 등록된 아이템이 아니라, Item.Category.Weapon 태그까지 가진 아이템만 들어갈 수 있다.
무기 드롭
NativeOnDrop() 흐름
1. 드롭된 Operation이 UKOItemDragDropOperation인지 확인
2. 아이템이 있는 드래그인지 확인
3. Factory 아이템이면 거부
4. 인벤토리에서 시작된 드래그인지 확인
5. 드롭된 ItemId 확인
6. IsWeaponEquipmentItem()으로 무기 장비인지 검사
7. Source->Extract()로 인벤토리에서 1개 제거
8. 기존 장착 무기가 있으면 인벤토리로 반환
9. EquippedWeaponId에 새 무기 저장
10. 아이콘, 이름, 툴팁 갱신
이 과정에서 중요한 부분은 기존 무기 반환 처리다.
if (!EquippedWeaponId.IsNone())
{
const int32 Remaining = Inventory->TryAddItem(EKOSlotKind::Item, EquippedWeaponId, 1);
if (Remaining > 0)
{
ItemDragOperation->Source->Restore(DraggedItemId, Extracted);
return false;
}
EquippedWeaponId = NAME_None;
}
새 무기를 장착하기 전에 기존 무기를 인벤토리로 돌려보낸다.
만약 인벤토리가 가득 차서 기존 무기를 반환할 수 없다면, 방금 꺼낸 새 무기도 원래 위치로 복구한다.
이렇게 해서 장착 실패 시 아이템이 사라지지 않도록 처리했다.
인벤토리 컴포넌트 찾기 방식 정리
처음에는 InventoryPanelWidget에서 WeaponSlotWidget에 InventoryComponent를 넘겨주는 방식으로 접근했다.
하지만 기존 InventoryWidget은 이미 자기 내부에서 ResolveInventoryComponentIfNeeded()를 통해 인벤토리 컴포넌트를 직접 찾는 구조였다. 그래서 무기 슬롯도 같은 방식으로 정리했다.
SetInventoryComponent()
= 외부에서 명시적으로 인벤토리 컴포넌트를 주입받는 방식
ResolveInventoryComponentIfNeeded()
= 주입받은 컴포넌트가 없으면 OwningPlayer 또는 Pawn에서 직접 찾는 방식
결과적으로 무기 슬롯도 인벤토리 위젯과 동일하게 동작하도록 만들었다.
외부에서 넘겨주면 그 컴포넌트를 사용
없으면 직접 PlayerController / Pawn에서 InventoryComponent 탐색
장착 해제
UnequipWeapon() 흐름
1. 장착된 무기가 있는지 확인
2. 인벤토리 컴포넌트 확인
3. 장착된 무기를 인벤토리에 TryAddItem()
4. 성공하면 EquippedWeaponId를 None으로 변경
5. UI 갱신
정리
- DT_Equipment 추가
- LoadSubsystem에서 장비 테이블 로드
- ItemLibrary에서 장비/무기 판별 함수 추가
- WBP_InventoryPanel에 WeaponSlotWidget 추가
- 무기 슬롯 드롭 처리
- 무기 장착 시 인벤토리에서 수량 차감
- 기존 무기 교체 처리
- 장착 해제 함수 추가
- 무기 슬롯 아이콘/이름 갱신
- 무기 슬롯 툴팁 표시
다음 단계
- 장착 무기 메시를 캐릭터 소켓에 붙이기
- GAS GrantedSet 또는 GameplayEffect 적용
- 장착 상태 저장/로드
- 무기 슬롯 우클릭 해제 입력 정리
기존 인벤토리 시스템 안에 장비 개념을 확장하였고,
무기도 여전히 Item으로 관리하면서, 장비 판별은 별도의 DT_Equipment에서 처리하도록 분리하였다.
'Unreal 최종 팀프로젝트' 카테고리의 다른 글
| [TIL] 개수 지정 제작 기능 | 최종 팀프로젝트 (0) | 2026.06.15 |
|---|---|
| [TIL] 설비 제작 UI | 최종 팀프로젝트 (0) | 2026.06.11 |
| [TIL] 레시피 슬롯 생성 | 최종 팀프로젝트 (0) | 2026.06.09 |
| [TIL] 맵, 미니맵 | 최종 팀프로젝트 (0) | 2026.06.08 |
| [TIL] 파이프 시스템 설계 | 최종 팀프로젝트 (0) | 2026.06.04 |