Item Data 리스트를 가지고 아이템에서 찾은 데이터를 기반으로 인벤토리 리스트에 추가한다.
인벤토리 리스트 정보를 바탕으로 인벤토리 슬롯 UI를 업데이트 한다.
인벤토리에 저장되는 아이템의 정보와 갯수에 대해서 관리하는 클래스
[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--;
}
}
인벤토리에 아이템을 추가하거나 삭제 관리를 하는 클래스
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();
}
}
}
}
인벤토리 창의 UI 슬롯은 Inventory 클래스의 InventoryItems 리스트의 정보를 통하여 이미지와 아이템 갯수를 업데이트 한다.
[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 = "";
}
}
}
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();
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.GetComponent<Player>() != null)
{
Inventory.instance.AddItem(itemData);
Destroy(gameObject);
}
}
inventoryItems = new List<InventoryItem>();
inventoryDictionary = new Dictionary<ItemData, InventoryItem>();
AddItem()이 호출되면 전달받은 ItemData를 가지고 인벤토리딕셔너리를 순회한다
(해당 ItemData가 딕셔너리에 이미 있는지 확인하는 작업)
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);
}
}
private void UpdatSlotUI()
{
for(int i = 0; i <inventoryItems.Count; i++)
{
itemSlot[i].UpdateSlot(inventoryItems[i]);
}
}