본문 바로가기
유니티/C#

17. 인벤토리 만들기-2

by 찡사랑방 2023. 4. 12.
728x90
728x90

인벤토리 만들기-2

 

1. 1) slot 스크립트 만든후 이전에 만들어논 slot prefab에 스크립트를 넣어준다.

    2) 스크립트

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

//item의 정보를 ui에 표시하는 매개체


public class Slot : MonoBehaviour
{
    public Item item;
    public Image itemIcon; //slot 자식 image

    public void UpdateUI()
    {
        itemIcon.sprite = item.itemIcon;
        itemIcon.gameObject.SetActive(true);
    }

    public void RemoveSlot() // slot 초기화
    {
        item = null; //null => 공백
        itemIcon.gameObject.SetActive(false);

    }
}

   2. 다른 스크립트들 수정 

 

1)inventoryUI

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InventoryUI : MonoBehaviour
{

    [SerializeField] GameObject inventoryPanel;//활성,비활성
    [SerializeField] Transform slotHolder;// slot들의 부모

    Slot[] slots;

    bool activeInventory; //엑티브 상태
    Inventory inven;

    //GetComponentsInChildren -> 자신과 자식을 참조해서 컴포넌트를 가지고 온다

    void Start()
    {
        inventoryPanel.SetActive(false); //게임 시작하면 감춰라
        slots=slotHolder.GetComponentsInChildren<Slot>();
        // inven = GameObject.Find("Player").GetComponent<Inventory>();  <= 첫번째 방법   //player가 소유한 컴포넌트, 오직 하나만 존재
        inven=FindObjectOfType<Inventory>(); //2번째 방법 (속도가 더 빠름)

    }


    void Update()
    {
        if (Input.GetKeyDown(KeyCode.I)) // on/off 방식
        {
            activeInventory = !activeInventory;
            inventoryPanel.SetActive(activeInventory);
        }
    }

    public void ReDrawSlot()
    {
        for (int i = 0; i < slots.Length; i++)
        {
            slots[i].RemoveSlot();
        }

        //보유한 아이템 만큼만 업데이트 필요

         for (int i = 0; i < Inventory.Instance.itemList.Count; i++)
        {
            slots[i].item=Inventory.Instance.itemList[i];
            slots[i].UpdateUI();

        }
    }

}

2) 변수 선언 없이 하고 싶다면 

 

Inventory 스크립트에 싱글턴을 만들면 가능

public class Inventory : MonoBehaviour
{

    public static Inventory Instance;
    private void Awake()
    {
        if (Instance==null) Instance = this;

    }
    
     public System.Action onChangeItem; //델리게이트(대리자)
    
    //소유한 아이템 저장
    public List<Item> itemList = new List<Item>();
}

   3. 플레이어가 아이템을 획득한다 

 

 Inventoy 스크립트 

  public List<Item> itemList = new List<Item>();

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Food")|| other.CompareTag("Soda"))
        {
            FieldItem fieldItem = other.GetComponent<FieldItem>();
            itemList.Add(CurrItem);
        }
    }
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Food") || other.CompareTag("Soda"))
        {
            FieldItem fieldItem = other.GetComponent<FieldItem>();
            itemList.Add(fieldItem.CurrItem);
            if (onChangeItem != null) onChangeItem.Invoke(); // invoke 델리게이트 실행시 사용
           
        }
    }

FieldItem 스크립트

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FieldItem : MonoBehaviour
{
    [SerializeField] Item item;

    //프로퍼티 -> item 변수에 간접적 접근(읽기 전용)
    public Item CurrItem { get { return item; } }
    
    //  public Item CurrItem => item; 로 람다식으로 변형 가능
}

마지막 inventoryui 스크립트 수정

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InventoryUI : MonoBehaviour
{

    [SerializeField] GameObject inventoryPanel;//활성,비활성
    [SerializeField] Transform slotHolder;// slot들의 부모

    Slot[] slots;

    bool activeInventory; //엑티브 상태
    Inventory inven;

    //GetComponentsInChildren -> 자신과 자식을 참조해서 컴포넌트를 가지고 온다

    void Start()
    {
        inventoryPanel.SetActive(false); //게임 시작하면 감춰라
        slots=slotHolder.GetComponentsInChildren<Slot>();
        // inven = GameObject.Find("Player").GetComponent<Inventory>();  <= 첫번째 방법   //player가 소유한 컴포넌트, 오직 하나만 존재
        inven=FindObjectOfType<Inventory>(); //2번째 방법 (속도가 더 빠름)
        inven.onChangeItem += ReDrawSlot;

    }


    void Update()
    {
        if (Input.GetKeyDown(KeyCode.I)) // on/off 방식
        {
            activeInventory = !activeInventory;
            inventoryPanel.SetActive(activeInventory);
        }
    }

     void ReDrawSlot()
    {
        for (int i = 0; i < slots.Length; i++)
        {
            slots[i].RemoveSlot();
        }

        //보유한 아이템 만큼만 업데이트 필요

        for (int i = 0; i < Inventory.Instance.itemList.Count; i++)
        {
            slots[i].item=Inventory.Instance.itemList[i];
            slots[i].UpdateUI();

        }
     
    }

}

 

4. 인벤토리창에서 아이템을 선택하면 아이템삭제 후 아이템에 따라 점수 차등적용

 

슬롯 스크립트 수정

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

//item의 정보를 ui에 표시하는 매개체

//slot을 클릭하면 아이템을 사용한다.
public class Slot : MonoBehaviour, IPointerClickHandler
{
    public Item item;
    public Image itemIcon; //slot 자식 image

    public int slotNum;

    public void UpdateUI()
    {
        itemIcon.sprite = item.itemIcon;
        itemIcon.gameObject.SetActive(true);
    }

    public void RemoveSlot() // slot 초기화
    {
        item = null; //null => 공백
        itemIcon.gameObject.SetActive(false);

    }

    public void OnPointerClick(PointerEventData eventData)
    {
        if (item!=null)
        {
            //목록에서 삭제
            Inventory.Instance.RemoveItem(slotNum);

        }
    }
}

 

플레이어 스크립트에 ↓ 추가

public void AddFood(int point)
    {
        food += pointPerFood;
        foodText.text = "+" + point + ",Food:" + food;

       
    }
728x90