다음은 본격적으로 인벤토리를 만들 차례.
우선 Item 클래스를 만들어 데이터를 옮겨다닐 상자를 만들고
Slot.cs가 아이템을 1개씩 옮겨다니며 인벤토리에서 작동해야하는 기능을 넣은 다음
Inventory.cs에서는 슬롯을 관리하게끔 만들고자 했다.
[System.Serializable]
public class IV_Item
{
public int ItemNum;
public string ItemName;
public string ItemDescript;
public int ItemCount;
public Sprite ItemSprite;
}
아이템 구분할 번호, 이름, 툴팁에 출력할 설명, 갯수, 스프라이트로 정했다.
public class IV_Slot : MonoBehaviour
{
public IV_Item CurrentItem;
public Image ItemImg;
public TextMeshProUGUI ItemCount;
public bool IsItemExist = false;
public void SetItem(IV_Item Item)
{
if (Item == null) return;
IsItemExist = true;
CurrentItem = Item;
ItemImg.sprite = Item.ItemSprite;
ItemImg.color = new Color(1, 1, 1, 1);
if (Item.ItemCount <= 1)
{
ItemCount.text = Item.ItemCount.ToString();
}
else
{
ItemCount.text = "";
}
}
public void AddCount(int Added)
{
if(CurrentItem.ItemCount + Added > 99)
{
// 일정 갯수 이상의 아이템이 되면 99개로 유지하고 넘친만큼 다른 아이템 슬롯에 동일한 아이템을 추가
return;
}
CurrentItem.ItemCount += Added;
ItemCount.text = CurrentItem.ItemCount.ToString();
}
public void ReduceCount(int Reduced)
{
if (CurrentItem.ItemCount - Reduced < 1)
{
// 1개 미만으로 줄어들 경우 슬롯 초기화
return;
}
CurrentItem.ItemCount -= Reduced;
ItemCount.text = CurrentItem.ItemCount.ToString();
}
}
다음은 슬롯.cs로 Item 클래스를 통해 가지고 있는 아이템을 저장하고
SetItem(Item)과 AddCount(int), ReduceCount(int)등 기본적인 함수들을 추가했다.
또한 슬롯이 비어있는지 확인하기 위한 IsItemExist도 추가했다.
public class IV_Inventory : MonoBehaviour
{
public HJ_Data Datas;
public List<IV_Slot> HotbarSlots = new List<IV_Slot>();
public List<IV_Slot> BagSlots = new List<IV_Slot>();
private void Awake()
{
Transform Hotbar = this.transform.GetChild(0);
Transform Bag = this.transform.GetChild(1);
for (int i = 0; i < Hotbar.childCount; i++)
{
HotbarSlots.Add(Hotbar.GetChild(i).GetComponent<IV_Slot>());
}
for (int i = 0; i < Bag.childCount; i++)
{
BagSlots.Add(Bag.GetChild(i).GetComponent<IV_Slot>());
}
if (this.gameObject.activeSelf)
{
this.gameObject.SetActive(false);
}
}
public void Toggle()
{
if (this.gameObject.activeSelf)
{
this.gameObject.SetActive(false);
}
else
{
this.gameObject.SetActive(true);
}
}
인벤토리에는 Slot들을 보관할 List를 2개 만들었는데 위쪽의 인벤토리에 우선적으로 아이템을 추가할 예정인지라
핫바와 연동해야할 슬롯들은 BotbarSlots라는 이름으로 구분해 넣었다.
Awake에서 가지고 있는 슬롯들을 자연스럽게 추가하고
Layout Group으로 프리팹으로 만들어둔 슬롯들을 자동 정렬하게끔 했다.
마지막으로 아이템 획득에 대한 부분인데...
추후 수정하긴 했지만 이쪽이 최초 함수이다.
💡 : 우선 이미 같은 아이템이 인벤토리에 있다면 그쪽에 추가하고 HotbarSlot에도 BagSlot에도 없으면
빈 슬롯을 찾아서 그곳에 추가하도록 해야겠다.
public void GainItem(int Itemnum, int Itemcount = 1)
{
int index = HotbarSlots.FindIndex(x => x.CurrentItem.ItemNum == Itemnum);
if(index != -1)
{
HotbarSlots[index].AddCount(Itemcount);
return;
}
index = BagSlots.FindIndex(x => x.CurrentItem.ItemNum == Itemnum);
if (index != -1)
{
BagSlots[index].AddCount(Itemcount);
return;
}
else
{
index = HotbarSlots.FindIndex(x => x.IsItemExist == false);
if(index != -1)
{
HotbarSlots[index].SetItem(Datas.ItemDatas.Find(x => x.ItemNum == Itemnum));
return;
}
index = BagSlots.FindIndex(x => x.IsItemExist == false);
if (index != -1)
{
BagSlots[index].SetItem(Datas.ItemDatas.Find(x => x.ItemNum == Itemnum));
return;
}
else
{
Debug.LogError("가방에 더이상 공간이 없습니다.");
}
}
}
public void LoseItem(int Itemnum, int Itemcount = 1)
{
}
우선 가독성이 별로이기도 하고 깊은 복사 문제 를 일으켰기 때문에 추후 수정했다.
여기까지 작동 시연
급하게 테스트 용으로 DropItem.cs를 만들어서 플레이어와 충돌시 아이템을 획득하도록 했다.
private void OnCollisionEnter2D(Collision2D collision)
{
IV_Player PL;
if (collision.gameObject.TryGetComponent<IV_Player>(out PL))
{
PL.Inventory.GainItem(CurrentItem.ItemNum);
this.gameObject.SetActive(false);
}
}
'📁 개발 히스토리' 카테고리의 다른 글
유니티 - 인벤토리 구현하기(4) (0) | 2025.02.23 |
---|---|
유니티 - 인벤토리 구현하기(3) (0) | 2025.02.23 |
유니티 - 인벤토리 구현하기(1) (0) | 2025.02.22 |
유니티 - 캐릭터를 따라다니는 텍스트 박스(3) (0) | 2025.01.13 |
유니티 - 캐릭터를 따라다니는 텍스트 박스(2) (0) | 2025.01.12 |