Unity

TIL: Unity 인벤토리 시스템 구현

우대비 2025. 5. 1. 21:23
반응형
TIL: Unity 인벤토리 시스템 구현

TIL: Unity 인벤토리 시스템 구현

2024년 3월 21일

인벤토리

오늘은 Unity에서 인벤토리 시스템을 구현한 내용들을 정리해보겠습니다. 특히 아이템 획득 UI, 인벤토리 슬롯 관리, 드래그 앤 드롭 기능을 구현하면서 얻은 경험을 공유합니다.

1. 아이템 데이터 구조 설계

public class ItemData
{
    public int Id {get; private set;}
    public string Name {get; private set;}
    public string Description {get; private set;}
    public string PrefabPath {get; private set;}
    public Sprite Icon {get; private set;}
    public bool CanStack {get; private set;}
    public int MaxStack {get; private set;}
    public EItemType ItemType {get; private set;}
    public EEquipType EquipType {get; private set;} 
}
  • 아이템 데이터는 읽기 전용 속성으로 설계하여 데이터 무결성을 보장
  • 스택 가능 여부와 최대 스택 수를 명시적으로 관리
  • 아이템 타입과 장비 타입을 enum으로 정의하여 타입 안전성 확보

2. 아이템 획득 UI 애니메이션 구현

public class ItemPickupUI : PopupUI
{
    [SerializeField] private Image itemIcon;
    [SerializeField] private TextMeshProUGUI itemName;
    [SerializeField] private Transform panel;

    protected override void Awake()
    {
        base.Awake();
        Managers.UserData.Inventory.onAddItem += Setup;
    }

    private void Setup(ItemData data)
    {
        Managers.UI.ShowPopupUI(this); 
        itemIcon.sprite = data.Icon;
        itemName.text = data.Name;

        // 기존에 panel에 적용된 모든 트윈을 종료
        panel.DOKill();

        panel.DOScale(1.2f, 0.2f).SetEase(Ease.InOutSine).OnComplete(() =>
        {
            DOVirtual.DelayedCall(0.5f, () =>
            {
                panel.DOScale(1f, 0.2f).SetEase(Ease.InOutSine).OnComplete(() =>
                {
                    Managers.UI.ClosePopupUI(this);
                });
            });
        });
    }
}
  • DOTween을 사용할 때는 기존 애니메이션을 `DOKill()`로 정리하는 것이 중요
  • 애니메이션 체이닝을 통해 자연스러운 시퀀스 구현 가능
  • 이벤트 기반 시스템을 활용하여 UI 업데이트 자동화

3. 인벤토리 슬롯 UI 구현

public class ItemSlotUI : MonoBehaviour, IPointerClickHandler
{
    [Header("Background")]
    [SerializeField] private Color defaultBackground;
    [SerializeField] private Color weaponBackground;
    [SerializeField] private Color equipmentBackground;
    [SerializeField] private Color consumableBackground;
    [SerializeField] private Color resourceBackground;
    [SerializeField] private Color placeableBackground;

    [Header("Info")]
    [SerializeField] private Image itemIcon;
    [SerializeField] private Image background;
    [SerializeField] private TextMeshProUGUI itemAmountText;

    private Dictionary colors;
    public ItemSlot ItemSlot {get; private set;}
    
    public void Setup(ItemSlot itemSlot)
    {
        ItemSlot = itemSlot;
        ItemSlot.onChangeStack += UpdateItemSlotUI; 
        UpdateItemSlotUI(itemSlot);
        onSetup?.Invoke(itemSlot);
    }
}
  • Inspector에서 직관적으로 설정할 수 있도록 Header 속성 활용
  • 이벤트 기반 업데이트로 성능 최적화
  • 아이템 타입별 시각적 구분을 위한 색상 시스템 구현

4. 드래그 앤 드롭 구현

public class MovingSlotUI : PopupUI
{
    [SerializeField] private RectTransform panelRT;
    [SerializeField] private Image itemImage;
    [SerializeField] private TextMeshProUGUI itemCountText;

    public void SetItem(ItemData itemData, int amount)
    {
        itemImage.sprite = itemData.Icon;
        itemCountText.text = amount.ToString();  
        Vector3 pos = panelRT.parent.InverseTransformPoint(Input.mousePosition);
        panelRT.localPosition = pos;
    }

    private void Update()
    {
        Vector3 pos = panelRT.parent.InverseTransformPoint(Input.mousePosition);
        panelRT.localPosition = pos;
    }
}
  • RectTransform을 활용한 UI 요소 위치 조정
  • 마우스 위치를 UI 좌표계로 변환하는 방법
  • Update 메서드에서 지속적인 위치 업데이트 구현

5. 개선할 점

  • 아이템 데이터 캐싱을 통한 성능 최적화
  • 드래그 앤 드롭 시 경계 체크 추가
  • 아이템 스택 분할 기능 구현
  • 인벤토리 정렬 기능 추가
다음에 할 일:
  • 아이템 필터링 시스템 구현
  • 인벤토리 확장 기능 추가
  • 아이템 툴팁 시스템 개선
반응형
LIST

'Unity' 카테고리의 다른 글

퀘스트 시스템  (2) 2025.04.28
TIL - Addressable 설계  (2) 2025.04.23
계층형 유한 상태 머신  (0) 2025.04.09
State Machine  (0) 2025.04.08
Unity Custom Editor - 윈도우 만들기  (0) 2025.04.06