본문 바로가기

내배켐 Unity TIL

Unity 59일차 TIL - Unity (2D ItemInventory2_InventoryUI)

(출처 : https://rito15.github.io/posts/unity-study-rpg-inventory/)

 

위에 링크에 있는 내용을 바탕으로 제작했다.

 

다음은 InventoryUI 부분이다.

 

InventoryUI는 SlotUI들을 관리하는 용도라고 생각한다.

초기에 SlotUI들을 생성해주고 List에 넣어서 이후에 data들을 관리하는 Inventory에서 수정을 하게되면 Inventory UI -> Slot UI 쪽으로 정보를 전달해주는 중간 다리 역할이다.

 

private Inventory inventory;
private InventoryUIDragAndDrop dragAndDrop;

[Header("Options")]
[Range(0, 11)]
[SerializeField] private int horizontalSlotCount = 11;   // 슬롯 가로 개수
[Range(0, 10)]
[SerializeField] private int verticalSlotCount = 3; // 슬롯 세로 개수
[SerializeField] private float sloatMarginX = 10f;    // 한 슬롯의 상하좌우 여백
[SerializeField] private float sloatMarginY = 8f;    // 한 슬롯의 상하좌우 여백
[SerializeField] private float contentAreaPadding = 25f; // 인벤토리 영역의 내부 여백
[Range(50, 140)]
[SerializeField] private float slotSize = 110f;

[Header("Connected Objects")]
[SerializeField] private RectTransform contentAreaRT;   // 슬롯들이 위치할 영역
[SerializeField] private GameObject slotUIPrefab;   // 슬롯의 프리팹

private List<ItemSlotUIs> slotUIList = new List<ItemSlotUIs>();
private Vector2 initPos = new Vector2(-705f, 240f);

initPos는 직접적으로 값을 입력하는 것보다는 emptyObject를 만들어서 사용하는 것도 좋은 방법일 것 같다.

 

private void Awake()
{
    InitSlots();
}

private void InitSlots()
{
    // 슬롯 프리팹 설정
    slotUIPrefab.TryGetComponent(out RectTransform slotRect);
    slotRect.sizeDelta = new Vector2(slotSize, slotSize);

    slotUIPrefab.TryGetComponent(out ItemSlotUIs itemSlot);
    if (itemSlot == null)
        slotUIPrefab.AddComponent<ItemSlotUIs>();

    slotUIPrefab.SetActive(true);

    Vector2 beginPos = initPos + new Vector2(contentAreaPadding+25f, -(contentAreaPadding+10f));
    Vector2 curPos = beginPos;

    slotUIList = new List<ItemSlotUIs>(verticalSlotCount * horizontalSlotCount);

    // 슬롯들 동적 생성
    for (int veritcal = 0; veritcal < verticalSlotCount; veritcal++)
    {
        for (int horizontal = 0; horizontal < horizontalSlotCount; horizontal++)
        {
            int slotIndex = (horizontalSlotCount * veritcal) + horizontal;

            var slotRT = CloneSlot();
            slotRT.pivot = new Vector2(0f, 0f);
            slotRT.anchoredPosition = curPos;
            slotRT.gameObject.SetActive(true);
            slotRT.gameObject.name = $"Item Slot [{slotIndex}]";

            var slotUI = slotRT.GetComponent<ItemSlotUIs>();
            slotUI.SetSlotIndex(slotIndex);
            slotUIList.Add(slotUI);
            if (slotIndex >= inventory.Capacity)
                slotUI.SetSlotsAccessibleState(false);

            curPos.x += (sloatMarginX + slotSize);
        }

        curPos.x = beginPos.x;
        curPos.y -= (sloatMarginY + slotSize);
    }

    if (slotUIPrefab.scene.rootCount != 0)
        Destroy(slotUIPrefab);
}

RectTransform CloneSlot()
{
    GameObject slotGo = Instantiate(slotUIPrefab);
    RectTransform rt = slotGo.GetComponent<RectTransform>();
    rt.SetParent(contentAreaRT);

    return rt;
}

중간에 만들어둔 뒤 아이템 인벤토리 쪽에서 장비창도 같이 제작을하게 되서 중간에 beginPos는 하드코딩 돼 있는 부분이 좀 아쉽다. 나중에 수정 예정

 

SlotUI를 List로 만들어두는 이유는 아이템 정보를 저장하고 업데이트하기 위한 용도이다.

 

// Public Methods

// 인벤토리 참조 등록
public void SetInventoryReference(Inventory inventory)
{
    this.inventory = inventory;
}

public void SetItemIcon(int index, Sprite icon)
{
    slotUIList[index].SetItem(icon);
}

public void SetEquipmentItemData(int index, EquipmentItemData data)
{
    slotUIList[index].SetItemEquipmentData(data);
}

public void SetItemAmountText(int index, int amount)
{
    slotUIList[index].SetItemAmount(amount);
}

public void HideItemAmountText(int index)
{
    slotUIList[index].SetItemAmount(1);
}

public void RemoveItem(int index)
{
    slotUIList[index].RemoveItem();
}

// 접근 가능한 슬롯 범위 설정
public void SetAccessibleSlotRange(int accessibleSlotCount)
{
    for (int i = 0; i < slotUIList.Count; i++)
    {
        slotUIList[i].SetSlotsAccessibleState(i < accessibleSlotCount);
    }
}

public void AddSlotUIList(ItemSlotUIs addSlot)
{

    slotUIList.Add(addSlot);
}

public int GetSlotUIListCount()
{
    return slotUIList.Count;
}

 

AddSlotUIList는 중간에 추가한 장비칸을 위해서 사용한다.

GetSlotUIListCount는 장비칸에 Slot을 slotUIList에 Add 해줄 때 Index값을 확인하기 위해서 사용한다.