스파르타코딩클럽 게임개발

오늘은 스파르타 코딩 클럽 unity 게임 개발 과정 46일차(인벤토리 시스템 3 크래프팅!)

코드천자문 2024. 1. 5. 02:35
반응형

인벤토리 시스템 3  크래프팅 !

클래스 이름 역할 설명
CragtingButton 크래프팅 버튼의 기능을 담당하며, 사용자가 아이템을 조합하여 새로운 아이템을 만들 수 있게 한다.
CraftringItemHolder 크래프팅에 사용될 아이템을 보관하고 관리한다. 사용자가 아이템을 드래그 앤 드롭하여 크래프팅에 사용할 수 있도록 한다.
ChestInventory 게임 내 상자와 같은 인벤토리 객체를 관리한다. 플레이어가 상자와 상호작용할 때 인벤토리 시스템을 표시하는 데 사용된다.
PlayerInventoryHolder 플레이어의 인벤토리 시스템을 관리한다. 플레이어가 소지한 아이템을 관리하고 필요에 따라 아이템을 추가하거나 제거하는 기능을 한다.
ResultItemHolder 크래프팅 결과물을 보관한다. 사용자가 아이템을 성공적으로 크래프팅하면, 생성된 아이템이 이 클래스에 저장된다.
InventoryUIController 게임의 다양한 인벤토리 UI를 관리한다. 인벤토리가 언제 어떻게 표시되어야 하는지 결정한다.
Interactor 플레이어와 게임 세계 내 다른 객체 간의 상호작용을 관리한다. 플레이어가 상호작용할 수 있는 객체를 감지하고 상호작용을 처리한다.

 

CragtingButton 클래스

역할

CragtingButton 클래스는 크래프팅 프로세스를 관리한다. 사용자가 인터페이스에서 아이템을 조합하여 새로운 아이템을 만들 수 있도록 한다.

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

public class CragtingButton : MonoBehaviour
{
    [SerializeField] private Transform cragtingPanel;
    [SerializeField] private Transform ResultPanel;
    public items items;
    private List<InventorySlot_Ui> inventorySlots = new();
    private List<string> itemData = new List<string>();
    private string itemRecipe;
    InventorySlot_Ui[] transforms;
    private void Awake()
    {
        transform.gameObject.GetComponent<Button>().onClick.AddListener(PerformCrafting);
    }

    private void PerformCrafting()
    {
        transforms = cragtingPanel.GetComponentsInChildren<InventorySlot_Ui>();
        foreach (var item in transforms)
        {
            if (item.AssignedInventorySlot.ItemData !=null)
            {
                if (item.AssignedInventorySlot.StackSize < 2)
                {
                    itemData.Add($"{item.AssignedInventorySlot.ItemData.name}");
                }
                else
                {
                    itemData.Add($"{item.AssignedInventorySlot.ItemData.name}({item.AssignedInventorySlot.StackSize})");
                }

            }
            else
            {
                itemData.Add(" ");
            }
        }

        itemRecipe = string.Join(',', itemData);

        Debug.Log(itemRecipe);
        Crafting();
        foreach (var item in transforms)
        {
            item.ClearSlot();
        }
        itemData.Clear();
    }

    private void Crafting()
    {
        foreach (var item in items.inventoryItemDatas)
        {
            if (item.itemRecipe == itemRecipe)
            {
                InventorySlot inventorySlot = new InventorySlot();
                inventorySlot.UpdateInventorySlot(item, 1);
                ResultPanel.GetComponentInChildren<InventorySlot_Ui>().Init( inventorySlot);
            }
        }
    }
}

주요 기능

  • Awake: 크래프팅 버튼에 클릭 이벤트 리스너를 추가한다. 이를 통해 사용자가 버튼을 클릭할 때 PerformCrafting 메서드가 호출된다.
  • PerformCrafting: 크래프팅을 수행하는 메서드다. 크래프팅 패널에서 사용자가 배치한 아이템들을 읽고, 이를 조합하여 새로운 아이템을 생성한다.
  • Crafting: 실제 아이템을 크래프팅하는 로직을 처리한다. 사용자가 조합한 아이템들이 특정 레시피와 일치하는 경우, 결과 아이템을 생성하고 인벤토리에 추가한다.

CraftringItemHolder 클래스

역할

CraftringItemHolder 클래스는 크래프팅에 사용될 아이템을 보관한다. 사용자가 아이템을 드래그 앤 드롭하여 크래프팅에 사용할 수 있도록 한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;

public class CraftringItemHolder : InventoryHolder
{
    [SerializeField] protected InventorySystem secondaryInventorySystem;

    public InventorySystem SecondaryInventorySystem => secondaryInventorySystem;

    public static UnityAction<InventorySystem> OnCraftringItemDisplayRequested;


    protected override void Awake()
    {
        base.Awake();

        secondaryInventorySystem = new InventorySystem(9);
    }

    private void Update()
    {
        if (Keyboard.current.qKey.wasPressedThisFrame)
        {
            OnCraftringItemDisplayRequested?.Invoke(secondaryInventorySystem);
        }
    }
}

주요 기능

  • Awake: 크래프팅을 위한 인벤토리 시스템을 초기화한다. 이 시스템은 사용자가 크래프팅에 사용할 아이템을 관리하는 데 사용된다.
  • Update: 사용자의 입력을 감지하여 크래프팅 아이템의 UI를 표시하거나 숨긴다. 예를 들어, 특정 키(Q)를 누르면 크래프팅 아이템이 표시된다.

ChestInventory 클래스

역할

ChestInventory 클래스는 게임 내 상자와 같은 인벤토리 객체를 관리한다.

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

public class ChestInventory : InventoryHolder , IInteractable
{
   public UnityAction<IInteractable> OnInteractionComplete { get; set; }

    public void Interact(Interactor interactor, out bool interactSuccessful)
    {
        OnDnamicInventoryDisplayRequested?.Invoke(primaryInventorySystem);
        interactSuccessful = true;
    }

    public void EndInteraction()
    {
        throw new System.NotImplementedException();
    }


}

주요 기능

  • Interact: 플레이어가 상자와 상호작용할 때 호출된다. 이 메서드는 상자의 인벤토리 시스템을 표시하는 데 사용된다.

PlayerInventoryHolder 클래스

역할

PlayerInventoryHolder 클래스는 플레이어의 인벤토리 시스템을 관리한다. 이 클래스는 플레이어가 소지한 아이템을 관리하고, 필요에 따라 아이템을 추가하거나 제거하는 기능을 한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;

public class PlayerInventoryHolder : InventoryHolder
{
    [SerializeField] protected int secondaryInventorySize;
    [SerializeField] protected InventorySystem secondaryInventorySystem;

    public InventorySystem SecondaryInventorySystem => secondaryInventorySystem;

    public static UnityAction<InventorySystem> OnPlaerBackpackDisplayRequested;


    protected override void Awake()
    {
        base.Awake();

        secondaryInventorySystem = new InventorySystem(secondaryInventorySize);
    }

    private void Update()
    {
        if (Keyboard.current.iKey.wasPressedThisFrame) OnPlaerBackpackDisplayRequested?.Invoke(secondaryInventorySystem);
    }

    public bool AddToInventory(InventoryItemData data, int amount)
    {
        if (primaryInventorySystem.AddToInventory(data, amount))
        {
            return true;
        }
        else if (secondaryInventorySystem.AddToInventory(data,amount))
        {
            return true;
        }

        return false;
    }
}

주요 기능

  • Awake: 플레이어의 인벤토리 시스템을 초기화한다. 이 시스템은 플레이어가 소지할 수 있는 아이템의 종류와 수량을 관리한다.
  • Update: 사용자의 입력을 감지하여 플레이어의 인벤토리 UI를 표시하거나 숨긴다. 예를 들어, I 키를 누르면 플레이어의 인벤토리가 표시된다.
  • AddToInventory: 새로운 아이

템을 플레이어의 인벤토리에 추가하는 메서드다. 아이템이 인벤토리에 추가되면, 사용자는 이 아이템을 사용할 수 있다.

ResultItemHolder 클래스

역할

ResultItemHolder 클래스는 크래프팅 결과물을 보관한다. 사용자가 아이템을 성공적으로 크래프팅하면, 생성된 아이템이 이 클래스에 저장된다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;

public class ResultItemHolder : InventoryHolder
{
    [SerializeField] protected InventorySystem secondaryInventorySystem;

    public InventorySystem SecondaryInventorySystem => secondaryInventorySystem;

    public static UnityAction<InventorySystem> OnCraftringItemDisplayRequested;


    protected override void Awake()
    {
        base.Awake();

        secondaryInventorySystem = new InventorySystem(1);
    }

    private void Update()
    {
        if (Keyboard.current.qKey.wasPressedThisFrame)
        {
            OnCraftringItemDisplayRequested?.Invoke(secondaryInventorySystem);
        }
    }
}

주요 기능

  • Awake: 크래프팅 결과를 위한 인벤토리 시스템을 초기화한다. 이 시스템은 크래프팅으로 생성된 아이템을 관리한다.
  • Update: 사용자의 입력을 감지하여 크래프팅 결과 아이템의 UI를 표시하거나 숨긴다.

InventoryUIController 클래스

역할

InventoryUIController 클래스는 게임의 다양한 인벤토리 UI를 관리한다. 이 클래스는 인벤토리가 언제 어떻게 표시되어야 하는지 결정한다.

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

public class InventoryUIController : MonoBehaviour
{
    public DynamicInventoryDisplay chestPanel;
    public DynamicInventoryDisplay PlayerBackpackPanel;
    public DynamicInventoryDisplay CraftingItemPanel;
    public DynamicInventoryDisplay ResultItemPanel;
    private void Awake()
    {
        chestPanel.gameObject.SetActive(false);
        PlayerBackpackPanel.gameObject.SetActive(false);
        CraftingItemPanel.transform.parent.parent.parent.gameObject.SetActive(false);
    }

    private void OnEnable()
    {
        InventoryHolder.OnDnamicInventoryDisplayRequested += DisplayInventory;
        PlayerInventoryHolder.OnPlaerBackpackDisplayRequested += DisplayPlayerBackpack;
        CraftringItemHolder.OnCraftringItemDisplayRequested += DisplayCrafting;
        ResultItemHolder.OnCraftringItemDisplayRequested += DisplayResult;
    }

    private void OnDisable()
    {
        InventoryHolder.OnDnamicInventoryDisplayRequested -= DisplayInventory;
        PlayerInventoryHolder.OnPlaerBackpackDisplayRequested -= DisplayPlayerBackpack;
        CraftringItemHolder.OnCraftringItemDisplayRequested -= DisplayCrafting;
        ResultItemHolder.OnCraftringItemDisplayRequested -= DisplayResult;
    }

    private void Update()
    {
        if (chestPanel.gameObject.activeInHierarchy && Keyboard.current.escapeKey.wasPressedThisFrame)
            chestPanel.gameObject.SetActive(false);

        if (PlayerBackpackPanel.gameObject.activeInHierarchy && Keyboard.current.escapeKey.wasPressedThisFrame)
            PlayerBackpackPanel.gameObject.SetActive(false);

        if (CraftingItemPanel.gameObject.activeInHierarchy && Keyboard.current.escapeKey.wasPressedThisFrame)
            CraftingItemPanel.transform.parent.parent.parent.gameObject.SetActive(false);
    }

    private void DisplayInventory(InventorySystem invToDisplay)
    {
        chestPanel.gameObject.SetActive(true);
        chestPanel.RefreshDynamicInventory(invToDisplay);
    }

    private void DisplayPlayerBackpack(InventorySystem invToDisplay)
    {
        PlayerBackpackPanel.gameObject.SetActive(true);
        PlayerBackpackPanel.RefreshDynamicInventory(invToDisplay);
    }

    private void DisplayCrafting(InventorySystem invToDisplay)
    {
        CraftingItemPanel.transform.parent.parent.parent.gameObject.SetActive(true);
        CraftingItemPanel.RefreshDynamicInventory(invToDisplay);
    }

    private void DisplayResult(InventorySystem invToDisplay)
    {
        ResultItemPanel.RefreshDynamicInventory(invToDisplay);
    }
}

주요 기능

  • 이벤트 리스너: 다양한 인벤토리 관련 이벤트에 대한 리스너를 등록하고, 이에 따라 적절한 인벤토리 UI를 표시하거나 숨긴다.
  • Update: 사용자의 입력을 감지하고, 특정 조건에서 인벤토리 UI를 표시하거나 숨긴다. 예를 들어, Escape 키를 누르면 현재 활성화된 인벤토리 UI를 숨긴다.

Interactor 클래스

역할

Interactor 클래스는 플레이어와 게임 세계 내 다른 객체 간의 상호작용을 관리한다.

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

public class Interactor : MonoBehaviour
{
    public Transform InteractionPoint;
    public LayerMask InteractionLayer;
    public float InteractionPointRadius = 1f;

    public bool IsInteracting { get; private set; }

    private void Update()
    {
        var colliders = Physics2D.OverlapCircleAll(InteractionPoint.position, InteractionPointRadius, InteractionLayer);

        if (Keyboard.current.eKey.wasPressedThisFrame)
        {
            for (int i = 0; i < colliders.Length; i++)
            {
                var interactable = colliders[i].GetComponent<IInteractable>();

                if (interactable != null) StartInteraction(interactable);
            }
        }
    }

    private void StartInteraction(IInteractable interactable)
    {
        interactable.Interact(this, out bool interactSuccessful);
        IsInteracting = true;
    }
    private void EndInteraction()
    {
        IsInteracting = false;
    }
}

주요 기능

  • Update: 매 프레임마다 호출되며, 플레이어가 상호작용할 수 있는 객체를 감지한다.
  • StartInteractionEndInteraction: 플레이어가 특정 객체와 상호작용을 시작하거나 종료할 때 호출된다. 예를 들어, 플레이어가 E 키를 누르면 가장 가까운 상호작용 가능 객체와 상호작용을 시작한다.

 

반응형