유니티/인벤토리

[Unity] 인벤토리 - 1. 기본 구현

이름?없음 2024. 2. 8. 21:08
반응형

이번 글에서는 유니티에서 인벤토리를 만드는 법을 알아보겠다

반응형

일단 인벤토리 구현을 위해서는 아이템을 먼저 만들 필요가 있다 먼저 아이템을 구현해 주었다

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(menuName = "SO/Item/Data")]
public class ItemDataSO : ScriptableObject
{

    //아이템의 스프라이트
    [field:SerializeField] public Sprite ItemSprite { get; protected set; }
    
    //아이템의 이름
    [field:SerializeField] public string ItemName { get; protected set; }

    //몇개까지 겹칠 수 있는지
    [field:SerializeField] public int MaxStackCount { get; protected set; }

    //아이템의 프리팹
    [field:SerializeField] public GameObject ItemPrefab { get; protected set; }

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Item : MonoBehaviour
{

    [field:SerializeField] public ItemDataSO itemData { get; private set; }


    //디버그용 코드
    private void OnMouseDown()
    {
        
        if(Inventory.Instance != null)
        {

            Inventory.Instance.AddItem(this);

        }

    }

#if UNITY_EDITOR

    //itemData설정시 자동으로 스프라이트등이 바뀌도록
    private void OnValidate()
    {
        
        if(itemData == null)
        {

            GetComponent<SpriteRenderer>().sprite = null;

        }
        else
        {

            GetComponent<SpriteRenderer>().sprite = itemData.ItemSprite;
            transform.name = itemData.ItemName;

        }

    }

#endif
}

 

나는 아이템의 데이터와 실질적인 아이템의 오브젝트를 나누어 구현하였다
그다음으로 기본적인 인벤토리의 로직을 작성해야 한다 나는 싱글톤 방식으로 인벤토리를 디자인하고 딕셔너리를 이용하여 아이템을 관리하는 방식으로 구현하였다

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Inventory : MonoBehaviour
{
    
    //아이템을 저장할 딕셔너리
    private Dictionary<ItemDataSO, int> itemContainer = new();
    public static Inventory Instance { get; private set; }

    private void Awake()
    {
        
        Instance = this;

    }

    public void AddItem(Item item)
    {

        //이미 같은종류의 아이템이 존재한다면?
        if (itemContainer.ContainsKey(item.itemData))
        {

            //MaxStackCount보다 덜 가지고있다면?
            if(item.itemData.MaxStackCount > itemContainer[item.itemData])
            {

                //카운트 1 증가
                itemContainer[item.itemData]++;

                //아이템 제거
                Destroy(item.gameObject);

            }

        }
        //같은 종류의 아이템을 가지고 있지 않다면
        else
        {

            //아이템 추가해주기
            itemContainer.Add(item.itemData, 1);

            //아이템 제거
            Destroy(item.gameObject);

        }

    }

    public void RemoveItem(ItemDataSO item, Vector2 pos)
    {
        
        //아이템이 존재한다면?
        if(itemContainer.ContainsKey(item))
        {

            //생성 해주기
            Instantiate(item.ItemPrefab, pos, Quaternion.identity);

            //카운트 1 빼주기
            itemContainer[item]--;

            //0이하로 떨어졌다면?
            if (itemContainer[item] <= 0)
            {

                //item 제거
                itemContainer.Remove(item);

            }


        }

    }

    private void OnDestroy()
    {
        
        Instance = null;

    }

}

 

이제 에디터로 가서 ItamDataSO를 하나 만들어준 뒤 값을 설정해 준다

그 후 빈오브젝트를 만든 뒤 SpriteRenderer와 Item, BoxCollider2D스크립트를 추가해 준다

ItemData에 아까 만든 SO를 추가해 준다

추가해 주면 스프라이트와 이름이 SO에 설정한 대로 바뀐 것을 볼 수 있다

이제 만든 아이템을 프리팹화 시킨 후 SO에 할당시켜 준다

그 후 빈 오브젝트를 만들고 Inventory스크립트를 추가해 준다

그 후 게임을 실행해서 아이템을 클릭해 보면 사라지는 것을 볼 수 있다

하지만 시각적으로 추가되는 것을 확인할 수 없다

이다음글에서는 인벤토리의 UI부분을 추가하여 시각적으로 확인해 보고 아이템을 버리는 기능을 구현해 보도록 하겠다

반응형