Today I Learn/25.06

📅06/16 | TIL 인벤토리 & 아이템 사용

오늘도즐겨 2025. 6. 16. 21:21

🎯 목표

  • 인벤토리 Slot
  • 아이템 사용

💡 인벤토리 

Item Slot 배열할당 + 인덱스값 적용

public class ItemSlot : MonoBehaviour
{
    public ItemData item;
    public UIInventory inventory;

    public int index;
    public bool equipped;
    public int quantity;
}

 

Inventory값 초기화

Start()에서 For문으로 인덱스 값 할당

해당 스크립트의 slots[i].inventory = this로 할당

private void Start()
{
    controller = CharacterManager.Instance.Player.controller;
    condition = CharacterManager.Instance.Player.condition;
    controller.inventory += Toggle;
    
    inventoryWindow.SetActive(false);
    slots = new ItemSlot[slotPanel.childCount];

    for (int i = 0; i < slots.Length; i++)
    {
        slots[i] = slotPanel.GetChild(i).GetComponent<ItemSlot>();
        slots[i].index = i;
        slots[i].inventory = this;
    }

    ClearSelectedItemWindow();
}

void ClearSelectedItemWindow()
{
    selectedItemName.text = string.Empty;
    selectedItemDescriptin.text = string.Empty;
    selectedStatName.text = string.Empty;
    selectedStatValue.text = string.Empty;
    
    useButton.SetActive(false);
    equipButton.SetActive(false);
    unequipButton.SetActive(false);
    dropButton.SetActive(false);
}

 

인벤토리 토글

public void Toggle() //인벤토리를 켜고 끄는 토글
{
    if (IsOpen())
    {
        inventoryWindow.SetActive(false);
    }
    else
    {
        inventoryWindow.SetActive(true);
    }
}

public bool IsOpen()
{
    return inventoryWindow.activeInHierarchy;
}

 

마우스 커서 토글 (PlayerController.cs) InputSystem에 OnInventory 추가

public void OnInventory(InputAction.CallbackContext context)
{
    if (context.phase == InputActionPhase.Started)
    {
        inventory?.Invoke();
        ToggleCursor();
    }
}

void ToggleCursor() //마우스 커서를 켜고 끄는 로직
{
    bool toggle = Cursor.lockState == CursorLockMode.Locked;
    Cursor.lockState = toggle ? CursorLockMode.None : CursorLockMode.Locked;
    canLook = !toggle;
}

 

카메라 회전 Bool값 활용

canLook = true : 인벤토리가 꺼져있을 경우

private void LateUpdate()
{
    if (canLook) //인벤토리가 꺼졌을때만, 돌아가도록
    {
        CameraLook();
    }
}

 

UIInventory Action 추가

CharacterManager.Instance.Player.addItem += AddItem;

💡 아이템 사용

아이템 슬롯에 아이콘을 세팅해주고 String값들을 넣어주고, 해당 버튼이 SetActive되어야함.

또한, 사용하기 버튼 클릭시, condition의 값을 조정해주고, UI Update 필수 !

 

아이템 슬롯에 세팅값 +  클리어값

public void Set()
{
    icon.gameObject.SetActive(true);
    icon.sprite = item.icon;
    quantityText.text = quantity > 1 ? quantity.ToString() : string.Empty;
    
    if (outline != null)
    {
        outline.enabled = equipped;
    }
}

public void Clear()
{
    item = null;
    icon.gameObject.SetActive(false);
    quantityText.text = string.Empty;
}

 

UIInventory

void UpdateUI()
{
    for (int i = 0; i < slots.Length; i++)
    {
        if (slots[i].item != null)
        {
            slots[i].Set();
        }
        else
        {
            slots[i].Clear();
        }
    }
}

 

선택된 아이템 하단 UI 세팅해주기

public void SelectItem(int index)
{
    if (slots[index].item == null) return;

    selectedItem = slots[index].item;
    selectedItemIndex = index;

    selectedItemName.text = selectedItem.displayName;
    selectedItemDescriptin.text = selectedItem.description;
    
    selectedStatName.text = string.Empty;
    selectedStatValue.text = string.Empty;

    for (int i = 0; i < selectedItem.consumables.Length; i++)
    {
        selectedStatName.text += selectedItem.consumables[i].type.ToString() + "\n";
        selectedStatValue.text += selectedItem.consumables[i].value.ToString() + "\n";
    }
    useButton.SetActive(selectedItem.type == ItemType.Consumable);
    equipButton.SetActive(selectedItem.type == ItemType.Equipable && !slots[index].equipped);
    unequipButton.SetActive(selectedItem.type == ItemType.Equipable && slots[index].equipped);
    dropButton.SetActive(true);
}

 

사용하기 또는 버리기 버튼 클릭

public void OnUseButton()
{
    if (selectedItem.type == ItemType.Consumable)
    {
        for (int i = 0; i < selectedItem.consumables.Length; i++)
        {
            switch (selectedItem.consumables[i].type)
            {
                case ConsumableType.Health:
                    condition.Heal(selectedItem.consumables[i].value);
                    break;
                case ConsumableType.Hunger:
                    condition.Eat(selectedItem.consumables[i].value);
                    break;
            }
        }
        RemoveSelectedItem();
    }
}

public void OnDropButton()
{
    ThrowItem(selectedItem);
    RemoveSelectedItem();
}

void ThrowItem(ItemData data)
{
    Instantiate(data.dropPrefab, dropPosition.position, Quaternion.Euler(Vector3.one * Random.value * 360));
}

 

초기화 함수

void RemoveSelectedItem() //사용시 또는 버릴시 호출할 함수
{
    slots[selectedItemIndex].quantity--;

    if (slots[selectedItemIndex].quantity <= 0)
    {
        selectedItem = null;
        slots[selectedItemIndex].item = null;
        selectedItemIndex = -1;
        ClearSelectedItemWindow();
    }
    UpdateUI();
}