ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스파르타3D서바이벌/아이템사용기능/유니티숙련주차
    스파르타 게임 개발 2024. 6. 4. 16:06

    인벤토리에 있는 아이템을 사용 하는 기능을 구현한다. 

     

    먼저 버튼들을 등록 해둔 것이 있을 것이다. 아이템 타입에 맞는 버튼이 활성화 되게 하고, 버튼을 클릭 했을 경우에 알맞는 로직이 실행 되게 하면 된다. 

     

    우린 먼저 아이템을 클릭 할 경우에 실행이 되게 할 코드를 작성 했었다. 

     public void OnClickButton()
     {
         inventory.SelectItem(index);
     }

    라는 코드를 이제 작성 해주도록 한다. (index는 ItemSlot에 저장 돼 있는 변수)

     

     

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

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

        selectedItemName.text = selectedItem.displayName;
        selectedItemDescription.text = selectedItem.description;

        selectedStatName.text = string.Empty;
        selectedStatValue.text = string.Empty;

      for (int i = 0; i < selectedIte.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);
    }

     

    첫 번째 코드를 보자면 if (slots[index].item == null) return;로 돼있다. 

    이 코드는 만약에 선택한 슬롯에 아이템Data가 없을 경우에는 실행 하지 않게 할 방어코드다. 

    그러니까 빈 슬롯 클릭 하면 이 함수가 실행이 되지 않게 하는 것이다. 빈슬롯 클릭방지. 

     

    그 다음에 만약 클릭 한 아이템 슬롯에 아이템이 있다면 selectedItem = slots[index].item; 라는 코드로 selectedItem에 값을 저장 하게 해준다. selectedItemIndex = index; 라는 코드로 index도 복사 해준다. 그리고 값을 복사 해왔으니 사용을 해주면 된다. 

    만들어둔 text들에게 선택 한 아이템 데이터로 표시가 되게 해준다.

     selectedItemName.text = selectedItem.displayName;
     selectedItemDescription.text = selectedItem.description;

     

    그리고 stat이름과 의 값은 Empty로 비워줄 것인데 이것은 소모품만 표시 되게 할 것이기 때문이다. 

    for (int i = 0; i < selectedIte.consumables.Length; i++)
        {
            selectedStatName.text += selectedItem.consumables[i].type.ToString() + "\n";
            selectedStatValue.text += selectedItem.consumables[i].value.ToString() + "\n";
        }

    라는 코드를 작성 해서 소모품일 경우에 소모품의 값과, 타입을 표시 되게 해준다. 

     

    그리고 알맞은 버튼을 활성화 하게 해주어야 하는데 여기서 enum을 활용하여 코드를 적으면 좋다.

     

    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);

     

    여기서 아이템 타입에 따라 사용, 장착, 해제 버튼을 나오게 해주면 된다. !slots[index].equipped라는 코드로써 장착이 돼 있지 않다면 장착 버튼 나오게, slots[index].equipped라는 코드로 장착중이라면 해제 버튼이 활성화 되게 해준다. 

     

    이렇게 해주면 아이템을 클릭 했을 때 알맞은 정보들이 Inventory 화면에 출력 되게 만들어 줄 수 있다. 

     

    이제 버튼을 누르면 장착, 사용, 버리기 등등을 구현들을 해주면 된다. 

     

    먼저 사용 버튼이다. 

    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();
        }
    }

    라는 코드로 작성 해주면 된다. 아이템 Type이 소모품일 경우에 실행이 된다.   selectedItem.consumables.Length;  코드로 반복문을 돌게 한다. 여기서 소모품의 배열은 소모품은 체력와 배고픔 둘 다 회복 하는 것이 있다. 그것을 다 적용 시키기 위해 이렇게 코드를 작성 한 것이고 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;

     

    이 코드로 알맞게 적용 시키게 한다. 

     

    public void Heal(float amount)
    {
        health.Add(amount); 
    }

    public void Eat(float amount)
    {
        hunger.Add(amount);
    }

     

    Heal과 Eat 함수. // 여기서 Health와 Hunger는 Condition 코드에 작성 돼 있는 변수들이다. 

     

      public void Add(float value)
      {
          curValue = Mathf.Min(curValue + value, maxValue);
      }

     

    Add함수.

     

    그리고 RemoveSelectedItem() 함수를 호출 해서 사용한 아이템은 제거 되게 한다. 

     

    private void RemoveSelectedItem()
    {
        slots[selectedItemIndex].quantity--;

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

     

    RemoveSelectedItem 함수. slots[selectedItemIndex].quantity--;를 빼준다. 그렇게 해서 0보다 작아지면 아래 코드가 실행이 된다. selectedItem 과 slots[selectedItemIndex].item 을 null로 비워주고 selectedItemIndex = -1;을 왜 1빼주는 건진 모르겠다. 

     

    그리고 ClearSelectedItemWindow 함수를 호출 해서 인벤토리에 UI오브젝트들을 기본상태로 바꿔준다. 

    private void ClearSelectedItemWindow()
    {
        selectedItemName.text = string.Empty;
        selectedItemDescription.text = string.Empty;
        selectedStatName.text = string.Empty;
        selectedStatValue.text = string.Empty;

        useButton.SetActive(false);
        equipButton.SetActive(false);
        unequipButton.SetActive(false);
        dropButton.SetActive(false);
    }

    ClearSelectedItemWindow함수.

     

    그리고 UpdateUI를 사용해서 ItemSlot의 오브젝트들도 갱신 해준다. 

     

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

    UpdateUI함수. item이 null이라면 Clear를 한다. item은 ItemData형 변수./ItemSlot에 있음.

     

    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;
    }

    Set과 Clear의 함수. ItemSlot 오브젝트를 설정 한다.  아이템이 있다면 아이템의 data를 표시, 없으면 빈 슬롯 표시

     

    이제 버리기를 구현 해본다. 

     

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

     

    을 만들어서 버리기 버튼이 눌리면 실행이 되게 한다. 

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

     

    ThrowItem 함수. 프리펩을 생성 하고, RemoveSeectedItem을 통해 아이템data를 비우는 함수다. 

     

    그리고 이제 마지막으로 아이템 장착만 구현을 하면 아이템 사용에 대한 구현은 끝이 난다.

     

     

Designed by Tistory.