public enum ItemType
{
Equipment,
Material,
Interactive
}
[CreateAssetMenu(fileName = "ItemData",menuName = "Data/Item")]
public class ItemData : ScriptableObject
{
public ItemType itemtype;
public string itemName;
public Image icon;
public string itemID;
protected StringBuilder sr = new StringBuilder();
private void OnValidate()
{
#if UNITY_EDITOR
string path = AssetDatabase.GetAssetPath(this);
itemID = AssetDatabase.AssetPathToGUID(path);
#endif
}
public virtual string GetDescription()
{
return "";
}
}
ScriptableObject로 에셋 형태로 아이템의 데이터를 관리하게 하였다.
ItemType
아이템이 재료인지, 장비인지, 상호작용 타입인지를 판단하기 위해 열거형으로 작성하였다.
StringBuilder
string을 자주 수정할 경우에는 StringBuilder을 사용하는 것이 효율적이다.
itemID
데이터의 경로를 아이디로서 가진다.
GetDescription
아이템의 설명을 가져온다. (지금은 따로 없다.)
#if Unity_Editor
itemID가 에디터에서 바로 수정되는 것을 원하기에 사용하였다.
using System;
using UnityEngine;
[Serializable]
public class InventoryItem
{
public ItemData data;
public int stack;
public InventoryItem(ItemData _newItemData)
{
data = _newItemData;
AddStack();
}
public void AddStack() => stack++;
public void RemoveStack() => stack--;
}
ItemData를 사용하여 InventoryItem을 만들었다.
(추후 ItemData를 상속받은 객체도 data로 사용가능.)
stack 아이템의 갯수이다. 현재 제한을 걸어두진 않았다.
public InventoryItem(ItemData _newItemData)
InventoryItem을 생성했을때 data가 비어있으면 안되도록 매개변수로 ItemData를 필요로 하게 하였다.
AddStack(),RemoveStack()
말그대로 아이템의 갯수를 +하거나 -한다.
public class Inventory : MonoBehaviour
{
public List<InventoryItem> inventory;
public Dictionary<ItemData, InventoryItem> inventoryDictionary;
private void Awake()
{
}
private void Start()
{
inventory = new List<InventoryItem>();
inventoryDictionary = new Dictionary<ItemData, InventoryItem>();
}
public void AddItem(ItemData _data)
{
if (_data.itemtype == ItemType.Equipment)
AddToInventory(_data);
}
public void AddToInventory(ItemData _itemData)
{
if(inventoryDictionary.TryGetValue(_itemData,out InventoryItem item))
{
item.AddStack();
}
else
{
InventoryItem newItem = new InventoryItem(_itemData);
inventory.Add(newItem);
inventoryDictionary.Add(_itemData,newItem);
}
}
public void RemoveItem(ItemData _itemData)
{
if(inventoryDictionary.TryGetValue(_itemData, out InventoryItem item))
{
if (item.stack > 1)
{
item.RemoveStack();
}
else
{
inventory.Remove(item);
inventoryDictionary.Remove(_itemData);
}
}
}
}
List
실제 인벤토리 역할을 수행하는 컬렉션이다.
Dictionary
ItemData로 InventoryItem을 검색할 수 있는 Dictionary이다.
(현재 가지고 있는 아이템 탐색에 쓰인다. ItemData로 검색가능하여 편하다.)
AddItem
Dictionary에 만약 ItemData가 있다면 item의 AddStack을 호출하고
없다면 InventoryItem을 만들어 매개변수로 ItemData를 넣어 List와 Dictionary에 추가한다.
RemoveItem
비슷하게 아이템의 Stack이 1보다 크다면 RemoveStack을 호출하고
그렇지 않다면 Dictionary와 List에서 ItemData를 삭제한다.