1 분 소요

Intro

  • 이번 포스팅에서는 아이템슬롯을 인벤토리 크기에 맞추어 동적으로 생성하는 코드를 작성해봅니다.

  • 이전 포스팅에서 만들어두었던 아이템슬롯UI 하나를 복제하여 인벤토리창을 채울 수 있도록 했습니다.

InventoryUI 클래스

  • InventoryUI 클래스는 인벤토리 UI에 대한 사용자의 모든 상호작용과 그래픽 레이캐스트를 담당합니다.

  • 또한 아이템슬롯UI들을 List형태로 모두 관리합니다.


public class InventoryUI : MonoBehaviour
{
    /*  ----------------- Option Fields ------------------ */
    #region
    [Header("# Options")]
    [Range(0, 10)]
    [SerializeField] private int horizontalSlotCount = 8;       // .. 슬롯 가로 개수
    [Range(0, 10)]
    [SerializeField] private int verticalSlotCount = 8;         // .. 슬롯 세로 개수
    [SerializeField] private float slotMargin = 8f;             // .. 슬롯의 여백
    [SerializeField] private float contentAreaPadding = 20f;    // .. 인벤토리 영역 내부 여백
    [Range(32, 96)]
    [SerializeField] private float slotSize = 64f;              // .. 슬롯 크기

    [Header("# Connected Objects")]
    [SerializeField] private RectTransform contentArea;         // .. 인벤토리 ContentArea
    [SerializeField] private GameObject slotUIPrefab;           // .. 복사할 슬롯 원본
    #endregion

    /*  -----------------  Unity Events  ----------------- */
    #region
    void Awake()
    {
        InitSlots();
    }
    #endregion

    /*  -----------------  Init Methods  ----------------- */
    #region
    // .. 인벤토리 슬롯 생성(가로 : horizontalSlotCount, 세로 : verticalSlotCount)
    private void InitSlots()
    {
        // .. 슬롯 프리팹 RT 정보
        slotUIPrefab.TryGetComponent(out RectTransform slotRect);
        // .. 슬롯 사이즈 설정
        slotRect.sizeDelta = new Vector2(slotSize, slotSize);

        slotUIPrefab.SetActive(false);

        Vector2 beginPos = new Vector2(contentAreaPadding, -contentAreaPadding);
        Vector2 curPos = beginPos;

        // .. 슬롯 동적으로 생성
        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);
                slotRT.anchoredPosition = curPos;
                slotRT.gameObject.SetActive(true);
                slotRT.gameObject.name = $"Item Slot [{slotIndex}]";    // .. 복제한 슬롯 오브젝트네임

                // .. 오른쪽 방향 증가
                curPos.x += (slotMargin + slotSize);
            }
            // .. 다음줄
            curPos.x = beginPos.x;
            curPos.y -= (slotMargin + slotSize);
        }

        // .. 프리팹이 아닌 경우 파괴(원본 파괴)
        if (slotUIPrefab.scene.rootCount != 0)
            Destroy(slotUIPrefab);

        // .. 슬롯 복제후 자식으로 넣어주기
        RectTransform CloneSlot()
        {
            GameObject slotGo = Instantiate(slotUIPrefab);
            RectTransform rt = slotGo.GetComponent<RectTransform>();
            rt.SetParent(contentArea);

            return rt;
        }
    }
    #endregion

}

  1. Option Fields에서 슬롯의 개수 및 크기, 여백등을 에디터에서 편집할 수 있도록 했습니다. 따라서 자기가 만든 인벤토리의 UI크기에 맞춰서 동적으로 슬롯을 만들 수 있도록 했습니다.

  2. Connected Object에 선언된 변수들에 에디터에서 인벤토리의 ContentArea의 RectTransform과 아이템슬롯프리팹을 연결해 주어야 합니다.

  3. 설정한 패딩값에 따라 슬롯을 생성할 위치를 잡아주고, 이중 for문을 돌며 아이템슬롯을 생성하여 ContentArea 자식 오브젝트들로 넣어줍니다.

댓글남기기