Unity 게임 개발 입문

Unity / 최종프로젝트 / 인벤토리

도도9999 2023. 11. 6. 08:55

ItemSO들의 ItemType - Weapon을 통해 Inventory의 Weapon만을 가져오는 WeaponInventory 구현

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using static UnityEditor.Progress;

public class WeaponInventory : MonoBehaviour
{
    [System.Serializable]
    public class WeaponInventoryItem
    {
        public int itemID;
        public int stack;

        public WeaponInventoryItem(int itemID = -1, int stack = 1)
        {
            this.itemID = itemID;
            this.stack = stack;
        }
    }

    public class WeaponBag
    {
        public List<WeaponInventoryItem> items = new List<WeaponInventoryItem>();
    }

    public WeaponBag weaponBag;

    private void Awake()
    {
        weaponBag = new WeaponBag();
    }

    private void Start()
    {
        AddWeapon(DataManager.Instance.GetItem(100));
    }

    public void AddWeapon(ItemSO itemSO)
    {
        if (itemSO.itemType != Enums.ItemType.Weapon)
        {
            return;
        }

        var item = weaponBag.items.Where(x => x.itemID == itemSO.itemID).FirstOrDefault();

        if (item != null && item.stack < itemSO.maxStack)
        {
            item.stack++;
        }
        else
        {
            weaponBag.items.Add(new WeaponInventoryItem(itemSO.itemID));
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static Inventory;

public class UI_WeaponInventory : MonoBehaviour
{
    [SerializeField] private Transform weaponSlotParent;
    [SerializeField] private Slot[] weaponSlots;

    private void Awake()
    {
        weaponSlots = weaponSlotParent.GetComponentsInChildren<Slot>();
    }

    public void FreshWeaponSlot()
    {
        if (Player.Instance == null)
        {
            Debug.LogError("Player.Instance is null");
            return;
        }
        if (Player.Instance.inventory == null)
        {
            Debug.LogError("Player.Instance.inventory is null");
            return;
        }
        if (Player.Instance.inventory.bag == null)
        {
            Debug.LogError("Player.Instance.inventory.bag is null");
            return;
        }
        if (weaponSlots == null)
        {
            Debug.LogError("weaponSlots is null");
            return;
        }

        var weaponItems = Player.Instance.inventory.GetWeaponItems();
        int i = 0;
        for (; i < weaponItems.Count && i < weaponSlots.Length; i++)
        {
            weaponSlots[i].Item = weaponItems[i];
        }
        for (; i < weaponSlots.Length; i++)
        {
            weaponSlots[i].Item = null;
        }
    }
}

 

Complete Order → Weapon Inventory → Item Click → Item Page → NPC에게 아이템 전달 → NPC는 사라짐

NPC 클릭 → Accept Order → Order Slot에 ItemID 전달하여 아이템 정보 출력
CompleteOrder 클릭 → 무기 전용 Inventory 노출 → 도끼 클릭
Give Weapon 클릭 → NPC의 의뢰 무기 ID와 플레이어가 인벤토리에서 선택한 무기 ID 값 비교
일치 → NPC 사라짐 → 작업창의 무기 사라짐

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;

public class WeaponPassBtn : MonoBehaviour
{
    [SerializeField] private Button weaponPassButton;
    [SerializeField] private ModalInventory modalInventory;
    [SerializeField] private NPCSpawner npcSpawner;
    [SerializeField] private NPCData npcData;
    [SerializeField] private GameObject POPUP_OrderSelect;
    [SerializeField] private GameObject POPUP_WeaponInventory;
    [SerializeField] private GameObject Modal_Weapon;
    public Inventory inventory;  


    private void Awake()
    {
        weaponPassButton.onClick.AddListener(() => CompleteOrder(npcData, UI_WeaponInventory.selectedItem));
        inventory = FindObjectOfType<Inventory>();

    }

    public void SetNPCData(NPCData npcData)
    {
        this.npcData = npcData;
    }


    public void CompleteOrder(NPCData npcData, ItemSO selectedItem)
    {
        ItemSO selectedWeapon = UI_WeaponInventory.selectedItem;
        if (selectedWeapon == null)
        {
            Debug.Log("선택된 무기가 없습니다.");
            return;
        }

        if (selectedItem != null)
        {
            if (npcData.orderItem.itemID == selectedItem.itemID)
            {
                Debug.Log("NPC가 의뢰한 아이템: " + npcData.orderItem.itemName);

                if (npcData.orderItem.itemName == selectedItem.itemName)
                {
                    Debug.Log("주문 일치: " + selectedItem.itemName);
                    npcData.isOrderAccepted = false;
                    npcData.npcGameObject.SetActive(false);

                    AcceptOrderBtn acceptOrderBtn = FindObjectOfType<AcceptOrderBtn>();
                    Sprite emptyOrderSprite = Resources.Load<Sprite>("EmptyOrder");

                    for (int i = 0; i < acceptOrderBtn.orderButtons.Count; i++)
                    {
                        Item itemComponent = acceptOrderBtn.orderButtons[i].GetComponent<Item>();

                        if (itemComponent != null && itemComponent.ItemID == npcData.orderItem.itemID)
                        {
                            acceptOrderBtn.orderButtons[i].image.sprite = emptyOrderSprite;
                            itemComponent.ItemID = 0; // 아이템 ID를 초기화합니다.
                            break;
                        }
                    }

                    POPUP_OrderSelect.SetActive(false);
                    POPUP_WeaponInventory.SetActive(false);
                    Modal_Weapon.SetActive(false);
                    inventory.SubItem(selectedItem);
                    inventory.UpdateInventoryUI();
                }
            }
        }
    }

}

 

 

이슈

-> NPC 프리팹 (NPC_UI 0) 은 [POPUP_OrderSelect], [ModalWeapn]을 할당받아야 하는데, 두 UI오브젝트가 비활성화 되어있는 상황이면 오브젝트들을 못찾아서 할당받지 못함.

-> 그래서 게임 시작 시에는 이 UI들을 활성화시킨 상태로 시작시키고 시작하자마자 비활성화 시킴

-> 그런데 침대 클릭 시 다음날로 넘어가는 개념으로 NPC가 새로 생성되며, 이때는 UI 오브젝트들이 비활성화 되어있던 상태라 옵젝을 못찾음

-> 그래서 침대 클릭 시 해당 UI들을 활성화시켰다 비활성화 되도록 만들어놓음

-> 0초만에 이가 진행되어 보이지는 않는데 가끔 활성화되는 프레임이 보일 때 있음

-> 가끔 보이건 말건 애초에 이렇게 구현해도 되는지 모르겠음

-> 결론 : 해당 구현을 수정하려면 비활성화된 오브젝트를 동적프리팹에 할당시키는 방법이 필요함