2 분 소요

Intro

저번 포스팅에서 만든 아이템 데이터를 가지고 할수있는 여러가지중

이번 포스팅에서는 대충 이런느낌의 인벤토리 시스템을 만들어보려합니다.

image

인벤토리 UI

인벤토리 UI는 본인이 하고싶은대로 만들면됩니다.

저는 아래와같이 세가지 영역으로 나누어 만들었습니다.

image

image

헤더영역

인벤토리 헤더부분은 마우스 드래그앤드롭을통해 인벤토리를 자유롭게 움직일 수 있으며, 닫기버튼을통해 인벤토리창을

비활성화 할수있습니다.

using UnityEngine.EventSystems;
using UnityEngine;
using UnityEngine.UI;

/// <summary> 인벤토리 드래그 앤 드롭 UI 이동/// </summary>
public class MovableHeaderUI : MonoBehaviour, IDragHandler, IPointerDownHandler
{
    // 이동될 UI
    [SerializeField] private Transform targetUI;

    private Vector2 beginPoint;
    private Vector2 moveBegin;

    private void Awake()
    {
        // 지정된 타깃UI가 없을경우 부모로 초기화
        if (targetUI == null)
            targetUI = transform.parent;
    }

    // 드래그하기
    void IDragHandler.OnDrag(PointerEventData eventData)
    {
        targetUI.position = beginPoint + (eventData.position - moveBegin);    
    }

    // 드래그 위치
    void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
    {
        beginPoint = targetUI.position;
        moveBegin = eventData.position;
    }

    // 인벤토리 닫기
    public void HideUI()
    {
        targetUI.gameObject.SetActive(false);
    }
}
  • 드래그앤드롭 기능을 구현하기위해 IDragHandler, IPointerDownHandler 인터페이스를 상속하여 구현해주었습니다.
  • HideUI 함수호출을통해 인벤토리창을 끌수있도록 했습니다.

image

아이템 영역

먼저 아이템 영역에 아이템슬롯들을 복제하여 인벤토리창을 채우는것부터 시작했습니다.

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

public class InventoryUI : MonoBehaviour
{
    [SerializeField] private RectTransform contentAreaRT;   // 아이템 영역
    [SerializeField] private GameObject itemSlotPrefab;     // 복제할 원본 슬롯 프리팹

    private int horizontalSlotCount = 6;                // 슬롯 가로갯수
    private int verticalSlotCount = 6;                  // 슬롯 세로갯수
    private float slotMargin = 9f;                      // 슬롯 여백
    private float contentAreaPadding = 8f;              // 인벤토리 영역 내부 여백
    private float slotSize = 81f;                       // 슬롯 사이즈

    private List<ItemSlotUI> slotUIList = new List<ItemSlotUI>();

    private void Awake()
    {
        InitSlots();
    }

    // 슬롯 영역 내에 슬롯 생성
    private void InitSlots()
    {
        // 슬롯 프리팹 설정
        itemSlotPrefab.TryGetComponent(out RectTransform slotRect);

        // 슬롯 사이즈 설정
        slotRect.sizeDelta = new Vector2(slotSize, slotSize);

        // 슬롯에 ItemSlotUI 스크립트 붙이기
        itemSlotPrefab.TryGetComponent(out ItemSlotUI itemSlot);
        if (itemSlot == null)
            itemSlotPrefab.AddComponent<ItemSlotUI>();

        // 원본 슬롯 비활성화
        itemSlotPrefab.SetActive(false);

        // 슬롯을 채울 시작위치, 현재위치
        Vector2 beginPos = new Vector2(contentAreaPadding, -contentAreaPadding);
        Vector2 curPos = beginPos;

        // 아이템 슬롯들을 담을 리스트
        slotUIList = new List<ItemSlotUI>(verticalSlotCount * horizontalSlotCount);

        // 슬롯 생성하기
        for(int j = 0; j<verticalSlotCount; j++)
        {
            for(int i = 0;i<horizontalSlotCount;i++)
            {
                int slotIndex = (horizontalSlotCount * j) + i;       // 슬롯 인덱스

                // 슬롯하나 복제
                var slotRT = CloneSlot();
                // 복제된 슬롯정보 설정
                slotRT.pivot = new Vector2(0f, 1f);                  // Left Top 기준
                slotRT.anchoredPosition = curPos;
                slotRT.gameObject.SetActive(true);
                slotRT.gameObject.name = $"Item Slot [{slotIndex}]"; // 하이어라키상 슬롯이름("Item Slot 0~35")

                var slotUI = slotRT.GetComponent<ItemSlotUI>();
                slotUI.SetSlotIndex(slotIndex);                      // 슬롯에 인덱스붙이기
                slotUIList.Add(slotUI);                              // 리스트에 생성된 슬롯정보 추가

                // 다음칸(가로)
                curPos.x += (slotMargin + slotSize);
            }

            // 다음줄(세로)
            curPos.x = beginPos.x;
            curPos.y -= (slotMargin + slotSize);
        }

        // 슬롯 원본파괴
        if (itemSlotPrefab.scene.rootCount != 0)
            Destroy(itemSlotPrefab);

        RectTransform CloneSlot()
        {
            GameObject slotGo = Instantiate(itemSlotPrefab);
            RectTransform rt = slotGo.GetComponent<RectTransform>();
            rt.SetParent(contentAreaRT);            // Content Area의 자식으로 들어가게 설정

            return rt;
        }
    }
}
  • 가로세로 6X6 개의 아이템슬롯을 인벤토리 영역내에 생성합니다.
  • 게임이 시작될 때 슬롯의 위치, 사이즈, 여백등의 정보를 설정하여 하나씩 생성하여 인벤토리 영역을 채워나갑니다.
  • 생성된 슬롯들은 리스트에 담아 저장합니다.

image

댓글남기기