공부일지

아이작 모작 팀 프로젝트 회고(작성중) 본문

UnityProjects/Inventory

아이작 모작 팀 프로젝트 회고(작성중)

이하택 2023. 10. 18. 10:12

(9/25~10/4)팀프로젝트 분석

게임 소개

  • 프로젝트 명 : 2D 로그라이크 게임
  • 프로젝트 소개 : “Babyjak”
    • 로그라이크 게임 “아이작”을 모작으로 <베이비작>을 제작.
  • 와이어프레임

담당한 역할

  • 아이템(체력 포션, 이동 속도 포션, 공격력 포션)과 인벤토리
  • UI와 시작씬 등

  • 스크립트
    • Inventory.cs
      using System.Collections;
      using System.Collections.Generic;
      using System.Linq;
      using TMPro;
      using UnityEngine;
      using UnityEngine.Events;
      using UnityEngine.InputSystem;
      using UnityEngine.InputSystem.Interactions;
      
      public class ItemSlot
      {
          public Items item;
          public int quantity;
      }
      public class Inventory : MonoBehaviour
      {
          public static Inventory Instance;
          public ItemSlotUI[] uiSlots;
          public ItemSlot[] slots;
      
          public GameObject inventoryWindow;
          public Transform dropPosition;
      
          [Header("Selected Item")]
          public ItemSlot selectedItem;
          public int selectedItemIndex;
          public TextMeshProUGUI selectedItemName;
          public TextMeshProUGUI selectedItemDiscription;
          public TextMeshProUGUI selectedItemStatNames;
          public TextMeshProUGUI selectedItemStatValues;
          public GameObject useButton;
      
          [Header("Events")]
          public UnityEvent onOpenInventory;
          public UnityEvent onCloseInventory;
      
          private void Awake()
          {
              Instance = this;
          }
          // Start is called before the first frame update
          void Start()
          {
              
          }
          private void OnEnable()
          {
              inventoryWindow.SetActive(false);
              slots = new ItemSlot[uiSlots.Length];
      
              for (int i = 0; i < slots.Length; i++)
              {
                  slots[i] = new ItemSlot();
                  uiSlots[i].index = i;
                  uiSlots[i].Clear();
              }
              ClearSelectedItemWindow();
          }
          public void Toggle()
          {
              if (inventoryWindow.activeInHierarchy)
              {
                  inventoryWindow.SetActive(false);
                  onCloseInventory?.Invoke();
              }
              else
              {
                  inventoryWindow.SetActive(true);
                  onOpenInventory?.Invoke();
              }
          }
          public bool IsOpen()
          {
              return inventoryWindow.activeInHierarchy;
          }
          public void AddItem(Items item)
          {
              if (item.canStack)
              {
                  ItemSlot slotToStackTo = GetItemStack(item);
                  if (slotToStackTo != null)
                  {
                      slotToStackTo.quantity++;
                      UpdateUI();
                      return;
                  }
      
                  ItemSlot emptySlot = GetEmptySlot();
      
                  if (emptySlot != null)
                  {
                      emptySlot.item = item;
                      emptySlot.quantity = 1;
                      UpdateUI();
                      return;
                  }
      
                  ThrowItem(item);
              }
          }
          void ThrowItem(Items item)
          {
              Instantiate(item.dropPrefab, dropPosition.position, Quaternion.Euler(Vector2.one * UnityEngine.Random.value * 360f));
          }
          public void UpdateUI()
          {
              for (int i = 0; i < slots.Length; i++)
              {
                  if (slots[i].quantity != 0)
                  {
                      uiSlots[i].Set(slots[i]);
                  }
                  else
                      uiSlots[i].Clear();
              }
          }
          ItemSlot GetItemStack(Items item)
          {
              for (int i = 0; i < slots.Length; i++)
              {
                  if (slots[i].item == item && slots[i].quantity < item.maxStackAmount)
                  {
                      return slots[i];
                  }
              }
      
              return null;
          }
          ItemSlot GetEmptySlot()
          {
              for (int i = 0; i < slots.Length; i++)
              {
                  if (slots[i].item == null)
                      return slots[i];
              }
      
              return null;
          }
          public void SelectItem(int index)
          {
              if (slots[index].quantity == 0)
                  return;
      
              selectedItem = slots[index];
              selectedItemIndex = index;
      
              selectedItemName.text = selectedItem.item.displayName;
              selectedItemDiscription.text = selectedItem.item.description;
      
              selectedItemStatNames.text = string.Empty;
              selectedItemStatValues.text = string.Empty;
      
              useButton.SetActive(true);
          }
          private void ClearSelectedItemWindow()
          {
              selectedItem = null;
              selectedItemName.text = string.Empty;
              selectedItemDiscription.text = string.Empty;
      
              selectedItemStatNames.text = string.Empty;
              selectedItemStatValues.text = string.Empty;
      
              useButton.SetActive(false);
          }
          public void ClearSlot(int index)
          {
              slots[index].item = null;
              slots[index].quantity = 0;
              uiSlots[index].Clear();
          }
      }
    • ItemSlot.cs
      using System.Collections;
      using System.Collections.Generic;
      using TMPro;
      using UnityEngine;
      using UnityEngine.UI;
      
      public class ItemSlotUI : MonoBehaviour
      {
          public Button button;
          public Image icon;
          public TextMeshProUGUI quantityText;
          private ItemSlot curSlot;
          private Outline outline;
      
          public int index;
          public bool equipped;
      
          private void Awake()
          {
              outline = GetComponent<Outline>();
          }
          private void OnEnable()
          {
              outline.enabled = equipped;
          }
          public void Set(ItemSlot slot)
          {
              curSlot = slot;
              icon.gameObject.SetActive(true);
              icon.sprite = slot.item.icon;
              quantityText.text = slot.quantity > 1 ? slot.quantity.ToString() : string.Empty;
      
              if (outline != null)
              {
                  outline.enabled = equipped;
              }
          }
          public void Clear()
          {
              curSlot = null;
              icon.gameObject.SetActive(false);
              quantityText.text = string.Empty;
          }
          public void OnBtnClick()
          {
              Inventory.Instance.SelectItem(index);
          }
      }

게임 내 기능들 분석

개선 사항들

인력 부족으로 순탄치 않았기에 부족한 점은 차고 넘치지만 꼽아보자면 아래와 같다.

  • 초기 구상의 디테일 부족
    • 이에 따른 아이템의 다양성의 부족
  • 인벤토리 UI의 칙칙한 외관
  • 몬스터들의 단조로운 공격패턴

느낀 점

개인 프로젝트에서는 손도 못 대었던 인벤토리 기능을 (물론 인벤토리 파트 강의의 도움이 있었지만) 마침내 구현해 내었기에 감회가 새로웠으며 재미를 붙이는 계기가 되었다.

따라서 인벤토리를 구현한 여러 스크립트들과 프로젝트들을 찾아보며 다양하게 익혀보고 싶다.

더 알아볼 점.

  • 인벤토리의 다양한 구현 방법 탐색과 그 중 메모리적으로 탁월한 방법 알아보기
  • 아이템 구현의 여러 방법 탐색

https://github.com/dodanrlrl/NewBaby


Uploaded by N2T

'UnityProjects > Inventory' 카테고리의 다른 글

코드 리뷰  (2) 2023.11.20
상세 아이템 Data 작성  (1) 2023.11.16
질문록  (1) 2023.11.15
중간 발표와 피드백  (1) 2023.11.14
백업  (0) 2023.11.09