내일배움캠프 43일차

박나연·2025년 6월 10일

내배캠

목록 보기
43/69

개인과제 하는 중...인벤토리

오늘의 키워드 : 간단한 인벤토리 구현해보기

오늘은 외출하고 오느라 실시간 수업을 못 들어서 그 부분은 적을 것이 없고 대신 개인과제 진행했던 걸 좀 적어보려 한다.

UIInventory.cs

public class UIInventory : MonoBehaviour
{
    [SerializeField] private UISlot slotPrefab;// UISlot 타입의 필드 추가 → UISlot 프리팹 추가
    [SerializeField] private Transform contentParent; //Transform 타입의 slot 부모 추가

    private List<UISlot> slots = new List<UISlot>(); //UISlot 타입의 리스트 추가

    private void Start()
    {
        InitInventoryUI();
    }

    public void InitInventoryUI()//UISlot 리스트, for문, Instantiate 등등 활용
    {
        foreach (var s in slots)
            Destroy(s.gameObject);
        slots.Clear();

        // player의 Inventory 리스트를 가져와
        var items = GameManager.Instance.player.Inventory;

        for (int i = 0; i < items.Count; i++)
        {
            var it = items[i];
            var slot = Instantiate(slotPrefab, contentParent);
            slot.SetItem(it);
            slots.Add(slot);
        }
    }
}
  • 저 foreach+clear 부분은 왜 필요한가?
    InitInventoryUI()가 여러번 불리게 되면 아이템이 중복 생성이 된다. 그래서 Destroy로 제거하는 방법을 쓰게 되었다.
  • for문 자세히 보기
    플레이어의 인벤토리 리스트를 가져온다.
    아이템 개수만큼 for문을 돌린다.
    Instantiate(slotPrefab, contentParent)로 슬롯을 동적 생성한다.
    slot.SetItem(it)으로 슬롯에 아이템 정보를 세팅한다.

Character.cs

public class Character
{
    public int BaseAttack { get; private set; }
    public int BaseDefense { get; private set; } 
    public int BaseHealth { get; private set; } 
    public int BaseCrit { get; private set; }

    // 착용한 아이템 보너스를 합산
    public int Attack => BaseAttack
                         + Inventory.Where(i => i.IsEquipped).Sum(i => i.AttackBonus);
    public int Defense => BaseDefense
                           + Inventory.Where(i => i.IsEquipped).Sum(i => i.DefenseBonus);
    public int Health => BaseHealth
                          + Inventory.Where(i => i.IsEquipped).Sum(i => i.HealthBonus);
    public int Crit => BaseCrit
                        + Inventory.Where(i => i.IsEquipped).Sum(i => i.CritBonus);

    public List<Item> Inventory { get; private set; }

    public Character(int baseAttack, int baseDefense, int baseHealth, int baseCrit)
    {
        BaseAttack = baseAttack;
        BaseDefense = baseDefense;
        BaseHealth = baseHealth;
        BaseCrit = baseCrit;
        Inventory = new List<Item>();
    }

    public void AddItem(Item item)
    {
        if (item == null) return;
        Inventory.Add(item);
    }

    public void Equip(Item item)
    {
        if (!Inventory.Contains(item)) return;
        item.IsEquipped = true;
    }

    public void UnEquip(Item item)
    {
        if (!Inventory.Contains(item)) return;
        item.IsEquipped = false;
    }
}
  • where과 Sum
    Inventory.Where(i => i.IsEquipped)는 장착된 아이템만 모아주는 필터이고
    .Sum(i => i.AttackBonus)는 필터링된 아이템들의 보너스를 전부 더한다.

  • Contains()는 리스트에 같은 인스턴스가 들어있는지 검사한다.


UISlot.cs

public class UISlot : MonoBehaviour
{
    [SerializeField] private Image slotImage;  // 아이템 아이콘
    [SerializeField] private GameObject equip; // 장착 중 표시 

    private Item item;
    private Button button;

    void Awake()
    {
        button = GetComponent<Button>();
    }

    public void SetItem(Item newItem)
    {
        item = newItem;
        button.onClick.AddListener(ToggleEquip);
        RefreshUI();
    }

    public void RefreshUI()
    {
        if (item != null)
        {
            slotImage.sprite = item.Icon;
            equip.SetActive(item.IsEquipped);
        }
        else
        {
            slotImage.sprite = null;
            equip.SetActive(false);
        }
    }

    private void ToggleEquip()
    {
        if (item == null) return;

        if (item.IsEquipped)
            GameManager.Instance.player.UnEquip(item);
        else
            GameManager.Instance.player.Equip(item);

        RefreshUI();
        UIManager.Instance.uiStatus.SetStatus(GameManager.Instance.player);
    }
}
  • RefreshUI()는 Item이 있으면 아이콘과 장착 표시를 업데이트하고 없으면 빈 슬롯이 된다.

  • ToggleEquip()item.IsEquipped상태에 따라 Equip, UnEquip이 호출된다. 그리고 RefreshUI()로 상태를 반영하고 캐릭터 스탯도 업데이트한다.

개인적으로 아이템같은 경우는 이런 방법말고 ScriptableObject를 사용해서 했으면 더 좋았을 것 같다. 과제에 그냥 스크립트라고 적혀있고 GameManager에 아이템 생성자 데이터를 추가하라길래 일단 이렇게 마무리하게 되겠지만 아쉬운건 사실이다.

마무리하며

뭔가 지금까지의 개인과제들 중에서 쉬운 편에 속하는 것 같다?? 과제에서 제시해준 방법대로 구현해봤는데 뭔가... 아이템 추가하는 방식에서 약간 의아해졌지만 뭐 이런 방법도 있구나~하면서 넘어가면 될 것 같다.

내일 할 일

내일은 주석 좀 달고 애니메이션 넣어서 조금 꾸미고 리드미 적어서 제출 할 예정이다. 그리고 오후에는 실시간 강의 놓쳤던 것들을 모아서 좀 들어보려고 한다. 그러다 보면 시간이 다 갈 것같은 느낌??

0개의 댓글