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

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

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

 

 

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

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

그리고 저희는 인벤토리의 배경과 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이라는 것들을 넣었죠? 그것도 만들어주어야 합니다.

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

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

 

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오브젝트를 복붙하면서 만들어주고 넣을 순서대로 각각 넣어줍니다. 이렇게 하면 인벤토리는 끝입니다.

 

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가 발생했다. 즉 인벤토리의 슬롯에 아이템이 가득차면 습득이 안되게 해주었습니다.

 

 

 

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

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

 

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