[유니티] Unity 인벤토리 및 아이템 습득 Inventory and GetItem

2D 유니티로 만드는 게임의 인벤토리 및 아이템 습득

전 글에 이어서 이번엔 인벤토리를 만들어보겠습니다.

 

 

1. 인벤토리를 위한 Panel추가

etc-image-0

판넬을 추가하고 대충 보기좋게 설정해줍니다.

그리고 저희는 인벤토리의 배경과 Slot들을 가지런히 놓기위한 Gid Layout Goup을 추가하여 이렇게 설정해줍시다.

대충 설정해보시면 금방 이해됩니다. 그리고 밑에 Inventory스크립트를 추가해줍니다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemInventory : MonoBehaviour
{
    public static ItemInventory instance;
    public ItemSlot[] Itemslots;
    public int selectedItemIndex = -1; // Item Slot Index

    private void Awake()
    {
        if (instance != null && instance != this)
            Destroy(this.gameObject);
        else
            instance = this;
    }

    public bool AddItem(string itemName, Sprite itemSprite, Item itemObject)
    {
        for (int i = 0; i < Itemslots.Length; i++) {
            if (Itemslots[i].isUse && Itemslots[i].item.item_number == itemObject.item_number) //If you have an item that's the same as one in the slots, add 1 to nowCount
            {
                Debug.Log("Item Add");
                Itemslots[i].item.now_Count = Mathf.Min(Itemslots[i].item.now_Count + 1, Itemslots[i].item.max_count); // nowCount 1 add.
                Itemslots[i].UpdateItemCountText(); // Text Update
                return true;
            }
        }
        for (int i = 0; i < Itemslots.Length; i++)
        {
            if (!Itemslots[i].isUse)
            {
                Itemslots[i].itemName = itemName;
                Itemslots[i].itemSprite = itemSprite;
                Itemslots[i].isUse = true;
                Itemslots[i].item = itemObject;
                // 여기에 Image 컴포넌트를 업데이트하는 코드를 추가합니다.
                Itemslots[i].Item_image.sprite = itemSprite;
                Itemslots[i].Item_image.enabled = true; // 이미지를 활성화합니다.
                Itemslots[i].item.now_Count += 1; //That's now_Count 1 Add
                Itemslots[i].UpdateItemCountText(); // Text Update
                return true; // 아이템을 성공적으로 추가했음
            }
        }
        return false; // 인벤토리가 가득 참
    }


    public void UseSelectedItem() //아이템 사용
    {
        if (selectedItemIndex >= 0 && selectedItemIndex < Itemslots.Length && Itemslots[selectedItemIndex].isUse)
        {
            Itemslots[selectedItemIndex].UseItem(); // 선택된 아이템 사용
            // 추가적인 로직, 예를 들어 아이템 슬롯 초기화
        }
    }

 

우선 이 스크립트를 넣어줍시다. 그리고 한가지 더 만들어야합니다. 위에 사진을 보면 Inventory 인스펙터에 slot이라는 것들을 넣었죠? 그것도 만들어주어야 합니다.

etc-image-1

이렇게 각각 Image UI로 넣어줍니다. ItemSlot도 image고 그냥Image도 image UI입니다.

ItemSlot은 아이템을 넣기위한 것, 그냥 Image는 아이템의 배경을 꾸미기위한 것입니다.

 

etc-image-2

ItemSlot의 Inspector입니다. 해당슬롯에 아이템의 이미지를 넣기위해 만들어줍니다.

이제 ItemSlot을 구현해보겠습니다.

 

ItemSlot코드

public string itemName; //아이템의 이름
    public Sprite itemSprite; //슬롯에 표시될 아이템의 이미지
    public bool isUse; //사용중인지 여부
    public Image Item_image;
    public Item item; // 슬롯에 있는 아이템
    public Text itemCountText; // 아이템 수량 텍스트
    

    private void Awake()
    {
        Transform child = transform.Find("Image"); // 자식 오브젝트의 이름으로 찾기
        if (child != null)
            Item_image = child.GetComponent<Image>();
    }
    public ItemSlot()
    {
        itemName = "";
        itemSprite = null;
        isUse = false;
    }

    public void UseItem() //Item Use it
    {
        if (item != null)
        {
            item.Use_Effect(); // 아이템의 사용 효과를 발동
            if (item.item_type == Item.Item_Type.Potion_Parts) //포션류 아이템이면 하나 제거
            {
                item.now_Count -= 1;
                UpdateItemCountText();// 아이템 수량 텍스트 업데이트
            }

            // 아이템 사용 후 추가적인 로직, 예를 들어 아이템 제거나 아이템 슬롯 업데이트
            if (item.now_Count <= 0) //아이템 갯수가 1보다 작아지면
            {
                ClearSlot(); // 슬롯을 초기화

            }
        }
    }

    public void ClearSlot() //아이템 사용후 초기화나 갯수차감 로직구현예정
    {
        itemName = "";
        itemSprite = null;
        Item_image.sprite = null;
        Item_image.enabled = false;
        isUse = false;
        item = null;
    }

    public void UpdateItemCountText() //Text Update
    {
        if (item != null)
        {
            itemCountText.text = item.now_Count.ToString();
        }
    }

포션아이템을 예시로 들고온 코드입니다.

 

이제 저 슬롯들을 인벤토리에 각각 넣어주면됩니다.

 

 

인벤토리 오브젝트의 Inpector에 스크립트에 슬롯의 갯수를 입력해줍니다.

그러면 자동으로 저렇게 Element가 자동생성되는데 그 갯수만큼 Slot오브젝트를 복붙하면서 만들어주고 넣을 순서대로 각각 넣어줍니다. 이렇게 하면 인벤토리는 끝입니다.

etc-image-3

 

2. GetItem 구현

Item 스크립트에 GetItem 함수입니다. 전 글에서 오브젝트와 충돌시 이 함수를 불러온다고 했는데 

private bool GetItem(Collider2D player)
    {

           Debug.Log("포션 습득");
           if (ItemInventory.instance.AddItem(item_Name, item_sprite, this)) //바디인벤토리에 추가
           {
                 
           }
           else
           {
                Debug.Log("포션아이템 가득참");
                return false;
                // 인벤토리가 가득 차 있다면, 메시지를 표시하거나 다른 로직을 수행
           }
        return true;
        // 아이템 습득 로직
        // 예: 인벤토리에 아이템 추가, 플레이어에게 효과 적용 등
    }

이건 제 프로젝트의 함수 일부를 가져왔습니다.

우선 아이템과 충돌시 "포션습득"이라는 Debug로 충돌감지를 잘 확인해주고 인벤토리의 AddItem으로 충돌한 아이템의 이름과 이미지, this는 해당아이템 그 자체입니다. 이 3가지를 매개변수로 보내줍니다.

아이템인벤토리 함수의 AddItem을 보시면 3개의 매개변수를 받아서 해당 슬롯의 아이템의 이미지와 각종 변수들을 넣어주는 로직을 확인 할 수 있습니다. 똑같은 아이템이 들어가있으면 갯수를 추가하는 로직도 있지만 지금은 먹는 것만 구현되면 다른 로직구현은 간단하기때문에 추가 되는것만 잘 확인해주시면 됩니다.

else는 AddItem에서 false가 발생했다. 즉 인벤토리의 슬롯에 아이템이 가득차면 습득이 안되게 해주었습니다.

 

 

 

왼쪽 밑 인벤토리에 아이템이 습득되는 것을 확인할 수 있습니다.

사용은 키 입력 이벤트를 구현하면 금방 하실 수 있습니다.

 

뭔가 설명이 많이 부실해보이지만 지금 프로젝트가 저 혼자만 하는것이 아니라 다른 팀원들과 만들고 있어서 전부 보여드리지 못하네요.. 궁금한 점이 있다면 댓글을 통해 알려드리겠습니다.