🛠️ 오늘 한 작업
- 오늘은 내일 진행될 실전 모의 면접을 준비했습니다. 인성 면접으로 보신다고 하시기에 관련 질문으로 준비했습니다.
- 장비창 작업을 진행했습니다.
- 기존 드래그 앤 드롭 구조를
DragSlot,DropReceiver,ItemTransferService,DragPayload로 나누기 시작했습니다. - 장비창 수정 작업으로 장비 슬롯 검사와 장비창 텍스트 표시를 수정했습니다.
- 퀵슬롯 작업을 시작했습니다.
🎤 실전 모의 면접 준비
내일은 부트캠프에서 지원하는 실전 모의 면접 1일차가 예정되어 있습니다.
이번 면접에서는 우선 인성 면접을 본다고 해서, 오늘은 예상 질문에 대한 답변을 익히는 시간을 가졌습니다.
평소에는 코드나 기능 구현 쪽에 신경을 많이 쓰고 있었는데, 막상 면접 준비를 하려니까 제가 어떤 식으로 말해야 할지도 따로 정리할 필요가 있었습니다.
평소에 나 자신에 대한 질문에 답변을 잘 못하는 스타일이다 보니 저에 대한 설명과 공부 과정, 그리고 만약 회사에 들어가고 갈등이 있으면 어떤 식으로 해결할지에 대해 답변을 정리하는 시간을 가졌습니다. (너무 어려운 것입니다 〒▽〒)
-영상은 나중에 붙인거여서 현재 기록이랑 다를 수 있습니다. (참고용)
🧲 드래그 앤 드롭 구조 분리
오늘은 장비창 작업을 하면서 드래그 앤 드롭 구조도 다시 정리했습니다.
이전에는 슬롯 쪽에서 드래그와 드롭 처리를 같이 하려는 느낌이 강했는데, 점점 인벤토리, 장비창, 퀵슬롯이 연결되다 보니 한 곳에 몰아두기 어려워졌습니다.
그래서 드래그를 시작하는 슬롯은 DragSlot, 드롭을 받는 쪽은 DropReceiver, 실제 아이템 이동 처리는 ItemTransferService에서 담당하도록 구조를 나누기 시작했습니다.
DragPayload.cs - 드래그 정보 전달용 데이터
public struct DragPayload
{
public int fromIndex;
public int toIndex;
public SlotKind fromKind;
public SlotKind toKind;
public EquipSlotType fromEquipSlot;
public EquipSlotType toEquipSlot;
public QuickSlotType fromQuickSlot;
public QuickSlotType toQuickSlot;
}
DragPayload에는 어디서 드래그를 시작했는지, 어디에 드롭했는지, 인벤토리 인덱스인지 장비 슬롯인지 퀵슬롯인지 같은 정보를 담도록 했습니다.
이걸 만들면서 느낀 건, 드래그 앤 드롭은 단순히 아이콘을 움직이는 기능이 아니라는 점입니다. 결국 중요한 건 “아이템이 어디에서 어디로 이동하는가”였고, 이 정보를 제대로 들고 다녀야 뒤쪽 처리도 가능했습니다.
🔁 ItemTransferService로 이동 규칙 모으기
아이템 이동 처리는 ItemTransferService에서 분기하도록 만들었습니다.
지금은 인벤토리에서 인벤토리로 이동, 인벤토리에서 장비창으로 장착, 장비창에서 인벤토리로 해제, 인벤토리에서 퀵슬롯 등록, 퀵슬롯끼리 교환, 퀵슬롯 해제 흐름을 나눠보고 있습니다.
ItemTransferService.cs - 슬롯 종류에 따른 이동 처리
if (payload.fromKind == SlotKind.Inventory && payload.toKind == SlotKind.Inventory)
{
return inv.MoveOrSwap(payload.fromIndex, payload.toIndex);
}
if (payload.fromKind == SlotKind.Inventory && payload.toKind == SlotKind.Equipment)
{
return eq.TryEquipInventory(inv, payload.fromIndex, payload.toEquipSlot);
}
if (payload.fromKind == SlotKind.Inventory && payload.toKind == SlotKind.Quick)
{
return quickSlot.BindFromInventory(inv, payload.fromIndex, payload.toQuickSlot);
}
이전처럼 슬롯마다 직접 처리하면 처음에는 편해 보이지만, 기능이 늘어날수록 예외 처리가 흩어질 가능성이 커 보였습니다.
그래서 실제 이동 규칙은 서비스 쪽에 모아두는 방향으로 바꾸고 있습니다. 아직 완전히 정리된 구조라고 보기는 어렵지만, 인벤토리 / 장비창 / 퀵슬롯을 계속 연결해야 하니 이쪽이 더 낫다고 판단했습니다.
⚔️ 장비창 장착 조건 수정
장비창 쪽에서는 아이템이 잘못된 슬롯에 들어가지 않도록 검사하는 부분을 수정했습니다.
예를 들어 머리 장비는 머리 슬롯에만 들어가야 하고, 무기는 무기 슬롯에만 들어가야 합니다. 단순히 장착 가능한 아이템인지 확인하는 것만으로는 부족해서, 드롭된 장비 슬롯과 아이템 타입이 맞는지도 확인해야 했습니다.
Equipment.cs - 장착 슬롯 검사
private bool IsSlotCompare(ItemType itemType, EquipSlotType slot)
{
return itemType switch
{
ItemType.Head => slot == EquipSlotType.Head,
ItemType.Body => slot == EquipSlotType.Body,
ItemType.Leg => slot == EquipSlotType.Leg,
ItemType.Shoes => slot == EquipSlotType.Shoes,
ItemType.Bag => slot == EquipSlotType.Bag,
ItemType.Weapon => slot == EquipSlotType.Weapon,
ItemType.Accessory => slot == EquipSlotType.Accessory1 || slot == EquipSlotType.Accessory2,
_ => false
};
}
이 부분은 드래그 앤 드롭을 붙이면서 더 중요해졌습니다. 더블클릭 장착처럼 자동으로 슬롯을 찾아주는 방식과 달리, 드래그 앤 드롭은 플레이어가 특정 슬롯에 직접 내려놓는 방식이기 때문입니다.
잘못된 슬롯에 내려놓았을 때 조용히 실패해야 하는지, 안내를 띄워야 하는지는 아직 더 봐야겠지만, 최소한 데이터가 잘못 들어가는 건 막아야 했습니다.
🧾 장비창 텍스트 수정
장비창 텍스트 표시도 수정했습니다.
장비창에 들어가는 아이템이라고 해서 전부 같은 방식으로 텍스트를 보여줄 수는 없었습니다. 근접 무기나 방어구는 내구도를 보여주는 게 맞고, 원거리 무기는 수량을 보여주는 게 더 자연스러웠습니다.
가방은 단순 수량보다 추가 인벤토리 슬롯 수를 보여주는 쪽이 더 의미가 있어서, 장신구 데이터에서 추가 슬롯 값을 읽어 표시하도록 수정했습니다.
UIEquipment.cs - 무기 / 가방 텍스트 분기
if (slot == EquipSlotType.Weapon)
{
if (itemDB.TryGetWeapon(stack.itemId, out var weapon)
&& (WeaponCategory)weapon.WeaponCategory == WeaponCategory.Ranged)
{
weaponCountTXT.text = stack.count.ToString();
}
else if (stack.HasRuntime)
{
text.text = $"{stack.runtime.durability}/{stack.runtime.maxDurability}";
}
}
else if (slot == EquipSlotType.Bag)
{
if (DataManager.Instance.ItemDB.TryGetAccessory(stack.itemId, out var acc))
{
int extra = acc.ExtraInventorySlot;
bagText.text = extra > 0 ? extra.ToString() : "";
}
}
처음에는 장비창 텍스트를 단순하게 처리해도 될 줄 알았는데, 아이템 타입이 늘어날수록 표시 기준도 같이 늘어났습니다.
특히 무기는 근접/원거리로 나뉘고, 가방은 슬롯 수 증가와 연결되기 때문에 장비창에서도 아이템별 의미에 맞게 다르게 보여줘야 했습니다.
⚡ 퀵슬롯 기능 시작
오늘은 퀵슬롯 작업도 시작했습니다.
퀵슬롯은 인벤토리의 아이템을 직접 복사해서 들고 있는 구조가 아니라, 인벤토리에 있는 ItemStack을 참조하는 방식으로 잡았습니다.
등록 가능한 아이템은 우선 무기와 소비 아이템으로 제한했습니다. 장비나 기타 아이템까지 전부 퀵슬롯에 들어가면 규칙이 애매해질 수 있어서, 일단 사용할 가능성이 높은 아이템 위주로 막았습니다.
QuickSlot.cs - 인벤토리 아이템을 퀵슬롯에 등록
public bool BindFromInventory(Inventory inv, int fromIndex, QuickSlotType toQuick)
{
if (inv == null) return false;
if (fromIndex < 0 || fromIndex >= inv.ActiveSlotCount) return false;
if (inv.IsLockedSlot(fromIndex)) return false;
var stack = inv.GetSlot(fromIndex);
if (stack == null) return false;
var itemType = DataManager.Instance.ItemDB.GetItemType(stack.itemId);
if (itemType != ItemType.Weapon && itemType != ItemType.Consumable) return false;
quickSlots[toQuick] = stack;
EventManager.TriggerEvent(EventKey.QuickSlotChanged);
return true;
}
퀵슬롯끼리 서로 바꾸는 Swap도 추가했습니다. 그리고 인벤토리에서 해당 아이템이 사라졌을 때 퀵슬롯에서도 자동으로 빠지도록 InventoryChanged 이벤트를 보고 검사하는 흐름도 넣었습니다.
이 부분은 꽤 중요하다고 생각했습니다. 인벤토리에서 이미 사라진 아이템이 퀵슬롯에 계속 남아 있으면, 실제로 사용할 때 버그가 생길 가능성이 크기 때문입니다.
🖥️ 퀵슬롯 UI 표시
UIQuickSlot에서는 퀵슬롯에 등록된 아이템을 화면에 보여주는 작업을 시작했습니다.
슬롯마다 아이콘과 텍스트를 갱신하고, 소비 아이템은 수량을 표시하도록 했습니다. 무기는 원거리 무기라면 수량을 보여주고, 근접 무기라면 내구도를 보여주는 식으로 나눴습니다.
UIQuickSlot.cs - 아이템 타입에 따른 텍스트 표시
if (itemType == ItemType.Consumable)
{
texts[i].text = stack.count.ToString();
continue;
}
if (itemType == ItemType.Weapon)
{
if (itemDB.TryGetWeapon(stack.itemId, out var weapon))
{
bool isRanged = (WeaponCategory)weapon.WeaponCategory == WeaponCategory.Ranged;
if (isRanged)
{
texts[i].text = stack.count.ToString();
}
else
{
texts[i].text = stack.HasRuntime
? $"{stack.runtime.durability}/{stack.runtime.maxDurability}"
: "";
}
}
}
인벤토리와 장비창에서도 계속 나왔던 문제인데, 결국 아이템 텍스트는 아이템 타입마다 다르게 처리해야 했습니다.
퀵슬롯은 전투 중 바로 확인하는 UI라서, 수량인지 내구도인지 구분이 더 중요할 것 같습니다.
🧹 우클릭으로 퀵슬롯 해제
퀵슬롯에 등록된 아이템을 우클릭으로 해제하는 QuickSlotCancel도 추가했습니다.
QuickSlotCancel.cs - 우클릭 해제
public void OnPointerDown(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Right) return;
if (quickSlot == null) return;
quickSlot.Clear(type);
}
아직 최종 UX가 완전히 정해진 건 아니지만, 퀵슬롯은 잘못 등록했을 때 쉽게 해제할 수 있어야 한다고 생각했습니다.
드래그로 다시 빼는 방식도 필요하겠지만, 우클릭 해제는 테스트하면서도 편할 것 같아서 먼저 붙였습니다.
🤔 오늘 느낀 점
오늘은 면접 준비도 해야 했고, 기능 작업도 해야 해서 머리가 조금 분산된 날이었습니다.
그래도 개발 쪽에서는 드래그 앤 드롭 구조를 다시 나누고, 장비창 텍스트를 수정하고, 퀵슬롯을 시작했다는 점에서 꽤 중요한 작업이 있었습니다.
특히 퀵슬롯을 만들면서 인벤토리 아이템을 그대로 참조할지, 별도의 데이터를 들고 있을지 고민이 됐습니다. 일단은 인벤토리의 ItemStack을 참조하는 방식으로 갔는데, 이 방식은 인벤토리에서 아이템이 사라질 때 퀵슬롯도 같이 정리해줘야 합니다.
그래서 InventoryChanged 이벤트를 기준으로 퀵슬롯의 참조가 아직 유효한지 검사하는 흐름을 넣었습니다. 이런 걸 보면 단순히 UI에 아이콘만 띄우는 게 아니라, 데이터 연결이 계속 신경 쓰이는 것 같습니다.
'내일배움캠프 본캠프' 카테고리의 다른 글
| [내일배움캠프 59일차 TIL] 최종 프로젝트 11일차 - 퀵슬롯 수정과 플레이어 인벤토리 연결 (0) | 2025.12.22 |
|---|---|
| [내일배움캠프 58일차 TIL] 최종 프로젝트 10일차 - 실전 모의 면접과 퀵슬롯 구조 수정 (0) | 2025.12.19 |
| [내일배움캠프 56일차 TIL] 최종 프로젝트 8일차 - 드래그 앤 드롭 시도와 아이템 텍스트 표시 정리 (0) | 2025.12.17 |
| [내일배움캠프 55일차 TIL] 최종 프로젝트 7일차 - 인벤토리 기능 구현과 구조 재정리 (0) | 2025.12.16 |
| [내일배움캠프 54일차 TIL] 최종 프로젝트 6일차 - 인벤토리 세팅과 아이템 데이터 흐름 시작 (0) | 2025.12.15 |