Inventory

Jihyun·2023년 12월 18일
0

Unity 2D

목록 보기
8/10
post-thumbnail

Inventory Sytem

Item Data 리스트를 가지고 아이템에서 찾은 데이터를 기반으로 인벤토리 리스트에 추가한다.
인벤토리 리스트 정보를 바탕으로 인벤토리 슬롯 UI를 업데이트 한다.

Inventory 기능

InventoryItem

인벤토리에 저장되는 아이템의 정보와 갯수에 대해서 관리하는 클래스

[Serializable]
public class InventoryItem 
{
    public ItemData data; //해당 인벤토리의 아이템이 가지고 있는 아이템 데이터
    public int stackSize; //인벤토리 내에서 저장된 갯수

    //새로운 인벤토리 아이템을 생성하는 생성자
    public InventoryItem(ItemData _newItemData)
    {
        //_newItemData는 itemName과 icon을 가진다
        data = _newItemData;

        AddStack();
    }

    public void AddStack()
    {
        stackSize++;
    }

    public void RemoveStack()
    {
        stackSize--;
    }
}

Inventory

인벤토리에 아이템을 추가하거나 삭제 관리를 하는 클래스

public class Inventory : MonoBehaviour
{
    public static Inventory instance;

    public List<InventoryItem> inventoryItems; //인벤토리에 저장된 아이템 객체를 저장하는 리스트
                                               //InventoryItem은 해당 아이템의 정보와 스택 크기를 갖는다
    public Dictionary<ItemData, InventoryItem> inventoryDictionary; //ItemData를 기반으로 InventoryItem을 빠르게 찾기 위한 딕셔너리

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

    private void Start()
    {
        inventoryItems = new List<InventoryItem>();
        inventoryDictionary = new Dictionary<ItemData, InventoryItem>();
    }

    //아이템을 인벤토리에 추가한다
    public void AddItem(ItemData _item)
    {
        //InventoryDictionary에서 동일한 아이템이 이미 인벤토리에 있는지 확인한다
        if(inventoryDictionary.TryGetValue(_item, out InventoryItem value))
        {
            value.AddStack();
        }
        else
        {
            //딕셔너리에 value가 없다 = 해당 아이템이 인벤토리에 없다 
            InventoryItem newItem = new InventoryItem(_item);
            inventoryItems.Add(newItem);
            inventoryDictionary.Add(_item, newItem);
        }
    }

    //아이템을 인벤토리에서 삭제한다
    public void RemoveItem(ItemData _item)
    {
        if(inventoryDictionary.TryGetValue(_item, out InventoryItem value))
        {
            //인벤토리에서 아이템 갯수가 1개라면 인벤토리에서 아이템 삭제
            if(value.stackSize <= 1)
            {
                //inventoryItems 리스트에서 삭제
                inventoryItems.Remove(value);
                //inventoryDictionary에서 삭제
                inventoryDictionary.Remove(_item);
            }
            else
            {
                //아이템 갯수가 1개 이상이다
                //아이템 갯수를 줄인다
                value.RemoveStack();
            }
        }
    }

}

Inventory UI

인벤토리 창의 UI 슬롯은 Inventory 클래스의 InventoryItems 리스트의 정보를 통하여 이미지와 아이템 갯수를 업데이트 한다.

  1. Image와 Text를 이용하여 Item Slot을 만들어준다
    아이템 슬롯 오브젝트에 들어갈 C# 스크립트 작성
    아이템 슬롯 오브젝트를 프리팹으로 만든다
[SerializeField] private Image itemImage;
[SerializeField] private Text itemText;

public InventoryItem item; //슬롯에 표시될 아이템   

public void UpdateSlot(InventoryItem _item)
{
        item = _item;

        itemImage.color = Color.white;

        if (item != null)
        {           
            itemImage.sprite = item.data.icon;

            if (item.stackSize > 1)
            {
                itemText.text = item.stackSize.ToString();
            }
            else
            {
                itemText.text = "";
            }
        }
    }
  1. 인벤토리를 관리할 매니저 오브젝트를 생성한다
    인벤토리 매니저 오브젝트에 Inventory 스크립트 추가
    Inventory 클래스에 아이템 슬롯을 관리하는 코드 추가
 private UI_ItemSlot[] itemSlot;
 
 private void Start()
{      
        itemSlot = inventorySlotParent.GetComponentsInChildren<UI_ItemSlot>();
}
 
 private void UpdatSlotUI()
    {
        //inventoryItems 리스트는 현재 인벤토리에 있는 모든 아이템을 저장하는 리스트이다        
        for(int i = 0; i <inventoryItems.Count; i++)
        {
            itemSlot[i].UpdateSlot(inventoryItems[i]);
        }
    }
    
    public void AddItem(ItemData _item)
    {       

        UpdatSlotUI();
    }
    
    public void RemoveItem(ItemData _item)
    {       

        UpdatSlotUI();
    }
    

기능 요약

  1. ItemObject 스크립트가 포함된 아이템 오브젝트가 플레이어와 충돌하면 Inventory 클래스의 AddItem 메서드를 호출한다.
    이때 인자로는 itemData를 통해 아이템 정보를 넘긴다.
private void OnTriggerEnter2D(Collider2D collision)
{
        if(collision.GetComponent<Player>() != null)
        {
              Inventory.instance.AddItem(itemData);
              Destroy(gameObject);
         }
}
  1. Inventory 클래스는 게임이 시작되면 리스트와 딕셔너리 초기화
inventoryItems = new List<InventoryItem>();
inventoryDictionary = new Dictionary<ItemData, InventoryItem>();

AddItem()이 호출되면 전달받은 ItemData를 가지고 인벤토리딕셔너리를 순회한다

(해당 ItemData가 딕셔너리에 이미 있는지 확인하는 작업)

  • 이미 딕셔너리에 있는 아이템이라면 InventoryItem의 AddStack() 메서드 호출여 인벤토리 아이템의 갯수 증가
  • 딕셔너리에 없는 아이템이라면 새로운 InventoryItem 객체를 생성하여 리스트와 딕셔너리에 추가
public void AddItem(ItemData _item)
{        
        if(inventoryDictionary.TryGetValue(_item, out InventoryItem value))
        {						
            value.AddStack();
        }
        else
        {
            InventoryItem newItem = new InventoryItem(_item);
            inventoryItems.Add(newItem);
            inventoryDictionary.Add(_item, newItem);
        }
}
  1. 인벤토리 슬롯 UI 업데이트
    슬롯 UI는 InventoryItems 리스트에 따라 업데이트 한다
private void UpdatSlotUI()
{      
        for(int i = 0; i <inventoryItems.Count; i++)
        {
            itemSlot[i].UpdateSlot(inventoryItems[i]);
        }
}
profile
잊어버려도 다시 리마인드 할 수 있도록 공부한 것을 기록합니다

0개의 댓글