스파르타 던전 만들기 - 개인프로젝트 트러블 슈팅

정광훈(Unity_9기)·2025년 5월 23일

TIL (Today I Learned)

목록 보기
43/110
post-thumbnail

아이템 슬롯

  • 의도했던 부분
    좌측 하단에 아이템 슬롯을 만들어서 Tab을 누르면 선택 슬롯이 바뀌고
    선택 중인 슬롯을 아웃라인으로 표시하면서
    슬롯을 선택하고 그 슬롯에 맞게 아이템이 추가되는 형식을 생각했었습니다.

  • 발생한 문제

크게 보면

  1. 아웃라인이 제대로 표시되지 않던 문제
    : 선택 중인 슬롯에 따라 아웃라인이 활성화되지 않던 현상

  2. 선택된 슬롯에 아이템이 추가되지 않고 첫 번째 슬롯에 추가되는 문제
    : 어떤 슬롯을 선택하더라도 무조건 첫 번째 슬롯에 아이템이 추가되는 현상

  3. 아이템을 추가하면 선택된 슬롯이 해제되는 문제
    : 슬롯에 상관없이 아이템을 추가하면 선택되어있던 슬롯이 해제가 되버리면서 아이템을 쓸 수 없었고 탭을 눌러야 다음 슬롯이 활성화 되던 현상


  • 해결방안
  1. 아웃라인이 제대로 표시되지 않던 문제

기존 코드

public void SelectItem(int index) 
{
	if (slots[index].item == null) return;      
		selectedItem = slots[index].item;     
		selectedItemIndex = index;  
}

직접적으로 이 코드에서 해결하는게 쉬울 것 같았다.

    public void SetOutlineActive(bool isActive) // 활성화를 선택하는 메서드
    {
        if (outline != null)
        {
            outline.enabled = isActive;
        }
    }

해당 메서드를 만들어

    public void SelectedSlot(int index)
    {
        // 0 <= selectedIndex < 2 && 선택된 슬롯이 존재하는가?
        if (selectedIndex >= 0 && selectedIndex < slots.Length && slots[selectedIndex] != null)
        {
            // 선택된 슬롯의 아웃라인을 비활성화 -> 이 슬롯은 이전 슬롯이 되어버림
            slots[selectedIndex].SetOutlineActive(false);
        }

        selectedIndex = index; // 선택된 인덱스 최신화 (슬롯 변경 후)

        if (selectedIndex >= 0 && selectedIndex < slots.Length && slots[selectedIndex] != null)
        {
            slots[selectedIndex].SetOutlineActive(true); // 현재 인덱스 슬롯의 아웃라인 활성화
            selectedItem = slots[selectedIndex].item; // 선택된 아이템 정보도 업데이트
        }
        else
        {
            selectedItem = null; // 유효하지 않은 인덱스인 경우 선택된 아이템 초기화
        }
    }

슬롯을 변경하면 활성화 메서드를 통해 조절하도록 수정하었다.

일단
if (selectedIndex >= 0 && selectedIndex < slots.Length && slots[selectedIndex] != null)
조건문을 추가해서 좀 더 명확한 상황을 만들었다.


  1. 선택된 슬롯에 아이템이 추가되지 않고 첫 번째 슬롯에 추가되는 문제
    void AddItem()
    {
        ItemData data = CharacterManager.Instance.Player.itemData;
        ItemSlot targetSlot = slots[selectedIndex];

        if (targetSlot.item == null) // 선택된 슬롯이 비어있다면
        {
            targetSlot.item = data; // data 아이템 데이터 정보를 할당 (아이템 넣기)
            targetSlot.quantity = 1; // 개수 1 추가
            UpdateUI();
            //  targetSlot.item에 data를 넘겼기 때문에 가지고 있던 아이템 정보는 필요가 없어짐 - 그래서 null로 초기화
            CharacterManager.Instance.Player.itemData = null; 
            SelectedSlot(selectedIndex); // 슬롯 업데이트
            return;
        }
        // 선택된 슬롯에 이미 아이템이 있고, 스택 가능하며, 최대 수량 미만이라면
        else if (targetSlot.item == data && data.canStack && targetSlot.quantity < data.maxStackAmount)
        {
            targetSlot.quantity++;
            UpdateUI();
            CharacterManager.Instance.Player.itemData = null;
            SelectedSlot(selectedIndex);
            return;
        }

        // 비어 있는 슬롯 가져옴
        ItemSlot emptySlot = GetEmptySlot();
        // 플레이어에 있는 아이템 데이터를 비움
        CharacterManager.Instance.Player.itemData = null;

        if (emptySlot != null) // 비어있는 슬롯이 있다면
        {
            emptySlot.item = data;
            emptySlot.quantity = 1;
            UpdateUI();
            CharacterManager.Instance.Player.itemData = null;
            SelectedSlot(selectedIndex);
            return;
        }

        //없다면 아이템 버림
        ThrowItem(data);
        CharacterManager.Instance.Player.itemData = null;
        Debug.Log($"인벤토리가 가득 차서 '{data.displayName}'을(를) 버림");
    }

ItemSlot targetSlot = slots[selectedIndex];
맨 위에 이 부분을 추가하면서
현재 선택된 슬롯이라는 변수를 만들어줬다.

if (targetSlot.item == null)
:조건문을 추가하면서
선택된 슬롯이 비어있는 상태인지 확인하고
비어있다면 그 슬롯에 아이템을 추가할 수 있도록 했다.

if (emptySlot != null)
: 이 조건문은 위의 조건들에 해당이 안 되는
빈 슬롯이라는 조건이다.

SelectedSlot(selectedIndex);
: 조건문 마지막에 추가하여 아웃라인과 아이템 정보를 업데이트를 하여
선택 상태가 풀리지 않도록 다시 한번 현재 선택된 슬롯을 활성화 시켜주는 용도이다.

여기에는 서로 다른 아이템이거나,
같은 아이템이더라도 수량이 다 차면 다음 슬롯에 들어가도록 한다.

하나의 변수와 조건문들을 통해 해결했다.

3번은 2번을 해결하면서 같이 해결되었다.


0개의 댓글