🛠️ 오늘 한 작업

  • 퀵슬롯 선택 테두리 표시를 계속 확인했습니다.
  • 아이템 사용 기능을 만들기 시작했습니다.
  • 장착여부나 퀵슬롯여부 작업으로 아이템의 장착 상태와 퀵슬롯 등록 상태를 구분할 수 있도록 수정했습니다.
  • 퀵슬롯 아이템 스왑 작업으로 같은 아이템을 퀵슬롯에 다시 넣을 때 기존 슬롯에서 이동되도록 수정했습니다.
  • 인벤 -> 퀵 스왑 가능 작업으로 인벤토리에서 퀵슬롯으로 아이템을 옮기는 흐름을 보완했습니다.
  • 퀵슬롯 아이템 사용 추가, 소비아이템 사용 작업을 진행했습니다.

 

📌 오늘 계획

오늘은 퀵슬롯 쪽을 계속 마무리하는 것을 목표로 잡았습니다.

전날까지 퀵슬롯을 플레이어 인벤토리와 연결하고, 번호 입력으로 선택하는 흐름까지 잡아봤는데 아직 어색한 부분이 많았습니다. 특히 선택된 퀵슬롯을 UI에서 확실하게 보여줘야 했고, 퀵슬롯에 등록된 아이템을 실제로 사용하는 기능도 필요했습니다.

  • 퀵슬롯 빨간 테두리 상시 적용하기
  • 아이템 사용하기 기능 만들기
  • 퀵슬롯 아이템 스왑 확인하기
  • 장착 여부와 퀵슬롯 여부를 구분하기

이제는 단순히 아이콘을 보여주는 단계가 아니라, 퀵슬롯에 들어간 아이템이 실제 게임 데이터와 맞게 움직여야 해서 계속 수정할 부분이 생겼습니다.

 

이미지는 개발 이후에 추가로 넣은거여서 진행상황이랑 다를 수 있습니다.(참고용)

 

🎒 아이템 장착 여부 / 퀵슬롯 여부 추가

먼저 ItemStack장착 여부와 퀵슬롯 등록 여부를 구분할 수 있는 값을 추가했습니다.

아이템이 인벤토리에만 있는지, 장착된 상태인지, 퀵슬롯에 등록된 상태인지 구분할 필요가 있었기 때문입니다. 특히 무기나 장비처럼 상태가 중요한 아이템은 단순히 아이템 ID만으로 보기 어렵습니다.

ItemStack.cs - 장착 / 퀵슬롯 상태 추가

public class ItemStack
{
    public long uid;
    public int itemId;
    public int count;
    public int maxStack;

    public bool isEquipped;
    public bool isQuickSlot;

    public ItemRuntime runtime;
    public bool HasRuntime => runtime != null;
}

장착할 때는 isEquipped를 true로 바꾸고, 기존에 장착되어 있던 아이템은 false로 돌리는 식으로 처리했습니다.

Equipment.cs - 장착 상태 변경

oldStack.isEquipped = false;
newStack.isEquipped = true;

아직 이 값들을 어디까지 활용할지는 더 봐야 하지만, 적어도 아이템 상태를 구분할 수 있는 기준을 만들기 시작했다는 점에서 의미가 있었습니다.

 

⚡ 퀵슬롯 아이템 스왑 수정

퀵슬롯에 같은 아이템을 다시 등록했을 때의 처리도 수정했습니다.

기존에는 이미 등록된 아이템이면 그냥 막는 방식에 가까웠는데, 실제로 사용해보면 같은 아이템을 다른 퀵슬롯으로 옮기고 싶을 수도 있습니다. 그래서 이미 등록된 아이템이 있다면 기존 슬롯을 찾아서 새 슬롯으로 이동시키는 방식으로 바꿨습니다.

QuickSlot.cs - 이미 등록된 슬롯 찾기

private bool TryFindboundSlot(QuickBinding binding, out QuickSlotType foundSlot)
{
    foreach (var slot in quickSlots)
    {
        var v = slot.Value;
        if (v.type != binding.type) continue;

        if (binding.type == QuickBindType.Uid && v.uid == binding.uid)
        {
            foundSlot = slot.Key;
            return true;
        }
    }

    foundSlot = default;
    return false;
}

그리고 인벤토리에서 퀵슬롯으로 등록할 때, 이미 같은 아이템이 다른 퀵슬롯에 있으면 Move를 호출하도록 수정했습니다.

QuickSlot.cs - 중복 등록 대신 이동 처리

if (TryFindboundSlot(binding, out var fromQuick))
{
    if (fromQuick.Equals(toQuick)) return false;

    Move(fromQuick, toQuick);
    return true;
}

이 부분은 퀵슬롯 UX를 생각하면 꽤 중요했습니다. 같은 아이템이 여러 칸에 중복으로 들어가는 것도 이상하고, 이미 등록되어 있다는 이유로 아무 일도 안 일어나는 것도 불편할 수 있기 때문입니다.

 

🖱️ 퀵슬롯 우클릭 해제 처리

기존에는 QuickSlotCancel이라는 별도 스크립트로 퀵슬롯 우클릭 해제를 처리하고 있었습니다.

그런데 슬롯 클릭 처리가 ItemSlot 쪽에 들어가면서, 퀵슬롯 우클릭 해제도 ItemSlot에서 같이 처리하도록 바꿨습니다.

ItemSlot.cs - 퀵슬롯 우클릭 해제

if (eventData.button == PointerEventData.InputButton.Right)
{
    if (slotKind == SlotKind.Quick)
    {
        var p = GameManager.Instance.ActivePlayer;
        if (p == null) return;

        p.quickSlot.Clear(quickSlotType);
    }

    return;
}

이렇게 바꾸면서 퀵슬롯 해제 처리를 별도 스크립트에 흩어두지 않고, 슬롯 입력 처리 쪽으로 모을 수 있었습니다.

아직 클릭 처리와 드래그 처리의 역할을 어디까지 나눌지는 더 봐야 하지만, 지금은 테스트하기 편한 방향으로 정리했습니다.

 

🧪 소비 아이템 사용 기능 시작

오늘은 아이템 사용 기능도 만들기 시작했습니다.

우선 소비 아이템을 사용했을 때 배고픔, 목마름, 스태미나 같은 캐릭터 수치가 회복되도록 연결했습니다. 진통제처럼 특정 아이템은 쇼크 수치를 줄이는 방식도 넣어봤습니다.

ItemSlot.cs - 소비 아이템 사용 처리

if (itemType == ItemType.Consumable)
{
    if (!db.TryGetConsumable(stack.itemId, out var consumable)) return;

    var character = gm.CurrentCharacter;

    character.AddHunger(consumable.HungerRecover);
    character.AddThirst(consumable.ThirstRecover);
    character.AddStamina(consumable.MaxStaminaBuffAdd);

    if (stack.itemId == 36300)
    {
        character.AddShock(-3);
    }

    inv.RemoveSlot(Index, 1);
    return;
}

아직은 WIP 상태입니다. 특히 수량 처리나 사용 가능한 상황 체크는 더 확인해야 합니다.

그래도 소비 아이템을 사용했을 때 캐릭터 상태값이 변하고, 인벤토리에서 수량이 줄어드는 기본 흐름은 잡기 시작했습니다.

 

🔢 퀵슬롯 수량 표시 수정

퀵슬롯에 표시되는 수량도 수정했습니다.

원거리 무기나 소비 아이템은 단순히 슬롯에 등록된 ItemStack만 보면 수량이 정확하지 않을 수 있습니다. 특히 원거리 무기는 장착된 수량과 인벤토리에 남아 있는 수량을 같이 봐야 했습니다.

Inventory.cs - 특정 아이템 보유 수량 확인

public int HasInventoryItem(int itemId)
{
    int count = 0;

    for (int i = 0; i < ActiveSlotCount; i++)
    {
        if (slots[i] == null) continue;

        if (slots[i].itemId == itemId)
        {
            count += slots[i].count;
        }
    }

    return count;
}

UIQuickSlot에서는 소비 아이템이면 인벤토리 전체에서 해당 아이템 수량을 가져오고, 원거리 무기면 장착 중인 수량까지 더해서 표시하도록 수정했습니다. 굉장히 귀찮은 작업이였습니다...  (。﹏。*)

UIQuickSlot.cs - 소비 아이템 / 원거리 무기 수량 표시

if (itemType == ItemType.Consumable)
{
    int consumableCount = inv.HasInventoryItem(itemId);
    texts[i].text = consumableCount.ToString();
}

if (isRanged)
{
    int count = gm.ActivePlayer.inventory.HasInventoryItem(itemId);
    var equippedItem = gm.ActivePlayer.equipment.GetEquipped(EquipSlotType.Weapon);

    if (equippedItem != null && equippedItem.itemId == itemId)
    {
        count += equippedItem.count;
    }

    texts[i].text = count.ToString();
}

수량 표시가 생각보다 까다로웠습니다. 아이템이 인벤토리에만 있는지, 장착된 상태인지, 퀵슬롯에 등록된 상태인지에 따라 화면에 보여야 하는 값이 달라질 수 있기 때문입니다.

 

📌 오늘의 회고

오늘은 퀵슬롯과 아이템 사용 쪽을 계속 수정했습니다.

처음에는 퀵슬롯에 빨간 테두리를 상시 적용하고, 아이템 사용 기능을 붙이는 정도로 생각했습니다. 그런데 막상 작업하다 보니 장착 여부, 퀵슬롯 여부, 소비 아이템 수량, 원거리 무기 수량까지 계속 연결해서 봐야 했습니다.

특히 소비 아이템은 단순히 인벤토리에서 하나 줄이면 끝나는 게 아니라, 캐릭터 상태값과 연결되어야 했습니다. 배고픔, 목마름, 스태미나, 쇼크 같은 값이 들어오면서 아이템 시스템이 점점 플레이어 상태 시스템과 붙기 시작한 느낌입니다.

다음에는 퀵슬롯에서 소비 아이템을 사용할 때 수량이 정확히 줄어드는지, 다 사용한 아이템이 퀵슬롯에서 어떻게 처리되는지 확인해야겠습니다. 오늘도 힘들었지만 보람 찬 하루였습니다. 남은 기간도 화이팅!!