🛠️ 오늘 한 작업
- 가방 장착 / 해제 로직을 수정했습니다.
- 장비 장착 시 플레이어의 공격력, 공격속도, 이동속도, 가방 슬롯 보너스가 반영되도록 연결했습니다.
- 가방 장착, 해제 고침, 인벤 스왑 고침 작업을 진행했습니다.
- 퀵슬롯 아이템 사용 로직을 보완했습니다.
- 소비 아이템과 원거리 무기는
itemId기준으로 퀵슬롯에 등록하고, 사용 시 하나씩 줄어들도록 수정했습니다. - 인벤토리 슬롯 더블클릭 시 소비 아이템 사용과 장비 장착이 가능하도록 작업을 시작했습니다.
📌 오늘 계획
오늘은 시간대별로 할 일을 나눠서 잡았습니다. 해야 할 게 많아서 조금 빡빡하게 적긴 했는데, 일단 할 수 있는 데까지 해보는 느낌이었습니다.
[9:00 ~ 1:00]
- 장비 장착 시 내구도 감소가 작동하는지 생각해보기
- 무기 공격력 / 공격속도 전달하기
- 인벤토리 무게 계산하기
- 신발 이동속도 보너스 계산하기
[2:00 ~ 6:00]
- 아이템 사용 로직을 퀵슬롯에도 연결하기
- 더블클릭 시 장비 장착되는 흐름 마무리하기
- 장비 장착 시 장비창이 열리는 흐름 생각하기
- 장비창 드래그 기능도 생각해보기
[7:00 ~ 9:00]
- 패널들 드래그 기능 만들기
🎒 가방 장착 / 해제 로직 수정
오늘 가장 많이 손본 부분 중 하나는 가방 장착과 해제였습니다.
가방은 일반 장비처럼 장착 슬롯에 넣고 빼면 끝나는 아이템이 아니었습니다. 장착하면 인벤토리 슬롯이 늘어나고, 해제하면 다시 슬롯이 줄어들기 때문에 예외 처리를 따로 봐야 했습니다.
특히 가방으로 늘어난 슬롯에 아이템이 들어있는 상태에서 가방을 해제하면 문제가 생깁니다. 그래서 가방을 해제하기 전에 추가 슬롯 쪽에 아이템이 남아 있는지 확인하는 CanUnEquipBag을 사용했습니다.
Inventory.cs - 가방 해제 가능 여부 확인
public bool CanUnEquipBag()
{
for (int i = BaseSlotCount; i < ActiveSlotCount; i++)
{
if (slots[i] != null) return false;
}
return true;
}
그리고 가방을 인벤토리로 되돌릴 때, 기본 슬롯 범위 안에 빈 칸을 찾아 넣는 흐름도 추가했습니다.
Inventory.cs - 기본 슬롯에서 빈 칸 찾기
public int FindEmptyIndex()
{
for (int i = 0; i < BaseSlotCount; i++)
{
if (slots[i] == null) return i;
}
return -1;
}
가방 해제는 생각보다 귀찮았습니다. 그냥 장비창에서 빼는 문제가 아니라, 인벤토리 슬롯 수 자체가 변하는 문제라서 잘못 처리하면 아이템이 잠긴 슬롯에 남거나 사라질 수 있습니다.
🔁 인벤토리 스왑 예외 처리
인벤토리 스왑도 같이 수정했습니다.
처음에는 장비 아이템은 기본 슬롯 안에만 있게 하려는 조건을 넣었다가, 이후 가방 해제 흐름과 충돌하는 부분이 있어서 다시 고치게 됐습니다.
최종적으로는 가방 해제 시 필요한 기본 슬롯 빈 칸을 따로 찾을 수 있도록 FindEmptyIndexInRange를 만들었습니다.
Inventory.cs - 특정 범위 안에서 빈 슬롯 찾기
public int FindEmptyIndexInRange(int startInclusive, int endExclusive, int exceptIndex = -1)
{
startInclusive = Mathf.Clamp(startInclusive, 0, MaxSlots);
endExclusive = Mathf.Clamp(endExclusive, 0, MaxSlots);
for (int i = startInclusive; i < endExclusive; i++)
{
if (i == exceptIndex) continue;
if (slots[i] == null) return i;
}
return -1;
}
이 부분은 아직도 조금 헷갈리는 쪽입니다. 가방을 장착하면 슬롯이 늘고, 해제하면 슬롯이 줄어드는데, 그 사이에 아이템이 어디에 있어야 안전한지 계속 따져봐야 했습니다.
그래도 가방은 인벤토리 시스템에서 중요한 예외라서, 초반에 확실히 잡아두는 게 맞다고 생각했습니다.
⚔️ 장비 효과를 플레이어 계산기에 연결
장비를 장착했을 때 실제 플레이어 스탯에도 영향을 주도록 연결했습니다.
무기를 장착하면 공격력과 공격속도를 넘기고, 신발을 장착하면 이동속도 보너스를 넘기고, 가방을 장착하면 인벤토리 슬롯 보너스를 적용하도록 했습니다.
Equipment.cs - 장비 효과 반영
if (slot == EquipSlotType.Weapon)
{
itemDB.TryGetWeapon(newStack.itemId, out var weapon);
gm.AttackDamage.SetWeaponAttack(weapon.Attack);
gm.AttackDelay.SetWeaponAtkDelay(weapon.AttackSpeed);
}
else if (slot == EquipSlotType.Shoes)
{
itemDB.TryGetAccessory(newStack.itemId, out var data);
gm.Movement.SetEquipMoveSpeedBonus(data.SpdBuffAdd);
}
else if (slot == EquipSlotType.Bag)
{
itemDB.TryGetAccessory(newStack.itemId, out var bag);
gm.inventory.EquipBag(bag.ExtraInventorySlot);
}
이 작업을 하면서 장비창이 단순히 아이콘만 보여주는 UI가 아니라는 걸 다시 느꼈습니다. 장착한 아이템이 실제 플레이어의 공격력, 공격속도, 이동속도, 인벤토리 슬롯 수에 영향을 줘야 하니, 플레이어 계산기 쪽과도 연결이 필요했습니다.
⚡ 퀵슬롯 아이템 사용 로직 변경
퀵슬롯 아이템 사용 로직도 수정했습니다.
이전에는 소비 아이템도 uid 기준으로 묶으려고 했는데, 실제로는 소비 아이템과 원거리 무기는 itemId 기준으로 보는 게 더 맞았습니다.
소비 아이템은 같은 종류의 아이템을 하나씩 사용하는 구조이고, 원거리 무기도 같은 아이템 ID의 수량을 기준으로 처리해야 했기 때문입니다.
QuickSlot.cs - 아이템 타입에 따른 바인딩 기준
if (type == ItemType.Weapon)
{
db.TryGetWeapon(stack.itemId, out var weapon);
if ((WeaponCategory)weapon.WeaponCategory == WeaponCategory.Ranged)
{
binding = QuickBinding.FromItemId(stack.itemId);
}
else
{
binding = QuickBinding.FromUid(stack.uid, stack.itemId);
}
}
else if (type == ItemType.Consumable)
{
binding = QuickBinding.FromItemId(stack.itemId);
}
이렇게 바꾸면서 퀵슬롯에 등록된 소비 아이템을 사용할 때 인벤토리에서 해당 아이템을 하나씩 줄이는 흐름을 만들 수 있었습니다.
QuickSlotController.cs - 소비 아이템 사용
if (itemType == ItemType.Consumable)
{
if (!db.TryGetConsumable(itemId, out var c) || c == null) return;
var player = GameManager.Instance.ActivePlayer;
if (player == null || player.CurrentCharacter == null) return;
player.CurrentCharacter.AddHunger(c.HungerRecover);
player.CurrentCharacter.AddThirst(c.ThirstRecover);
player.CurrentCharacter.AddStamina(c.MaxStaminaBuffAdd, player.Stamina.CalculateStamina());
if (!inv.TryRemoveByItemId(itemId, 1))
return;
if (inv.HasInventoryItem(itemId) <= 0)
quickSlot.Clear(slot);
return;
}
이제 퀵슬롯에 소비 아이템을 등록한 뒤 사용하면 하나씩 줄어드는 흐름을 만들었습니다. 아직 예외 처리는 더 봐야 하지만, 퀵슬롯이 실제 아이템 사용과 연결되기 시작했다는 점은 확실히 좋았습니다.
🖱️ 인벤토리 더블클릭 장착
인벤토리 슬롯을 더블클릭했을 때 장비가 장착되도록 하는 흐름도 추가했습니다.
소비 아이템이면 바로 사용하고, 장착 가능한 아이템이면 타입에 맞는 장비 슬롯을 찾아 장착하는 식으로 진행했습니다.
ItemSlot.cs - 더블클릭 장착
if (db.CanEquip(stack.itemId))
{
var type = db.GetItemType(stack.itemId);
EquipSlotType equipSlotType;
if (type == ItemType.Accessory)
{
if (eq.GetEquipped(EquipSlotType.Accessory1) == null)
{
equipSlotType = EquipSlotType.Accessory1;
}
else
{
equipSlotType = EquipSlotType.Accessory2;
}
}
equipSlotType = (EquipSlotType)type;
eq.TryEquipInventory(inv, Index, equipSlotType);
}
이 부분은 아직 더 다듬어야 할 것 같습니다. 특히 장신구처럼 슬롯이 두 개인 아이템은 자동으로 어떤 슬롯에 들어갈지 예외 처리가 필요합니다.
그래도 더블클릭으로 장착하는 기본 흐름을 붙이기 시작했다는 점에서는 의미가 있었습니다.
📌 오늘의 회고
오늘은 계획을 꽤 많이 잡았는데, 막상 해보니 가방 장착과 퀵슬롯 사용 로직만 해도 생각보다 시간이 많이 걸렸습니다.
가방은 그냥 장비 하나라고 생각하면 안 됐습니다. 장착하면 인벤토리 슬롯이 늘어나고, 해제하면 슬롯이 줄어들기 때문에 아이템 위치까지 같이 생각해야 했습니다. 이 부분 때문에 장착 / 해제 / 스왑 로직을 계속 수정하게 됐습니다.
장비 효과를 플레이어 계산기와 연결한 것도 의미 있는 작업이었습니다. 이제 장비창에 아이템을 넣는 것에서 끝나는 게 아니라, 무기 공격력이나 신발 이동속도 같은 값이 실제 플레이어 계산에 들어가기 시작했습니다.
퀵슬롯 사용 로직도 조금 더 정리됐습니다. 소비 아이템과 원거리 무기는 itemId 기준으로 처리하고, 근접 무기처럼 개별 상태가 중요한 아이템은 uid 기준으로 처리하는 방향이 더 맞는 것 같습니다.
아직 장비창 드래그나 창 열기/닫기 같은 UI 쪽은 많이 남아 있습니다. 그래도 오늘은 인벤토리, 장비, 퀵슬롯이 단순 UI에서 실제 플레이어 상태와 연결되는 쪽으로 한 단계 더 간 날이었습니다.
'내일배움캠프 본캠프' 카테고리의 다른 글
| [내일배움캠프 63일차 TIL] 최종 프로젝트 15일차 - 드랍 아이템 시스템 구현 시작 (0) | 2025.12.29 |
|---|---|
| [내일배움캠프 62일차 TIL] 최종 프로젝트 14일차 - 기술 모의 면접과 UI 사용성 개선 (0) | 2025.12.26 |
| [내일배움캠프 60일차 TIL] 최종 프로젝트 12일차 - 퀵슬롯 상태 표시와 소비 아이템 사용 기능 (0) | 2025.12.23 |
| [내일배움캠프 59일차 TIL] 최종 프로젝트 11일차 - 퀵슬롯 수정과 플레이어 인벤토리 연결 (0) | 2025.12.22 |
| [내일배움캠프 58일차 TIL] 최종 프로젝트 10일차 - 실전 모의 면접과 퀵슬롯 구조 수정 (0) | 2025.12.19 |