• Home
  • About
    • KKsDev photo

      KKsDev

      게임 프로그래머를 목표로 Unity, C#을 공부하고 있습니다.

    • Learn More
    • Email
    • Github
    • Steam
  • Posts
    • All Posts
    • All Tags
  • Projects

내일배움캠프 55일차 TIL 팀 프로젝트 아이템 조합 기능 구현

19 Oct 2023

Reading time ~2 minutes

오늘 배운 내용

  1. 팀 프로젝트 아이템, 인벤토리 구현



nbcbanner

팀 프로젝트 아이템 조합 기능 구현

이제 아이템 조합 기능을 만들 차례다 일단 아이템조합 정보에 대한 것들을 SO로 만들어서 생성해주었다.

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

[Serializable]
public class RecipeData
{
    public ItemSO itemSO;
    public int count;
}

[CreateAssetMenu(fileName = "CombinationData", menuName = "CombinationData/Default", order = 0)]

public class RecipeSO : ScriptableObject
{
    public List<RecipeData> requiredItems = new List<RecipeData>();

    public GameObject combinationItem;

    public GameObject Combination()
    {
        // UIManager가 들고있는 Inventory에 접근해서 아이템 갯수를 수정
        return Instantiate(combinationItem);
    }
}

그리고 이 조합 정보를 관리해줄 CombinationManager를 싱글톤 클래스로 만들어 줬다.

using System.Collections.Generic;
using UnityEngine;

public class CombinationManager
{
    private static CombinationManager _instance;
    public static CombinationManager Instance { get { return _instance ?? (_instance = new CombinationManager()); } }

    public RecipeSO[] Recipes { get; private set; }

    Dictionary<string, int> itemCount;

    public CombinationManager()
    {
        LoadAllRecipe();
    }
    
    public void LoadAllRecipe()
    {
        Recipes = Resources.LoadAll<RecipeSO>("Scriptable Objects/Objects/Recipe");
        
    }

    public List<RecipeSO> FindPossibleRecipe()
    {
        itemCount = GameManager.Instance.InventoryUI.itemCount;
        List<RecipeSO> possibleList = new List<RecipeSO>();

        foreach (RecipeSO recipe in Recipes) 
        {
            if (CheckRecipe(recipe.requiredItems))
            {
                possibleList.Add(recipe);
            }
        }

        return possibleList;
    }

    public bool CheckRecipe(List<RecipeData> list)
    {
        bool isPossible = true;

        foreach(RecipeData data in list) 
        {
            string key = data.itemSO.itemName;
            if (itemCount.ContainsKey(key) && itemCount[key] >= data.count)
            {
                continue;
            }
            else
            {
                isPossible = false;
                break;
            }
            
        }

        return isPossible;
    }

    public void Combination(RecipeSO recipes)
    {
        foreach(RecipeData data in recipes.requiredItems)
        {
            for(int i =0; i< data.count; i++)
            {
                int index = GameManager.Instance.InventoryUI.FindIndexItemSO(data.itemSO);
                GameManager.Instance.InventoryUI.DestroyItemFromInventory(index);
            }
        }
        GameObject go = GameObject.Instantiate(recipes.combinationItem);
        go.SetActive(false);
        go.transform.SetParent(GameManager.Instance.transform);
        GameManager.Instance.InventoryUI.AddItemToInventory(go.GetComponent<Item>());
        // 인벤토리에 생성된 아이템을 넣어줌
    }

SO들을 로드해서 관리하고 현재 내 인벤토리에 있는 아이템을 바탕으로

조합 가능한 아이템이 있는지 찾아준다. 그리고 마지막으로 조합버튼을 눌렀을때 아이템을 조합해준다.

public class CombinationButton : MonoBehaviour
{
    Action<int> Combination;
    private void Awake()
    {
        Combination += transform.parent.GetComponent<UICombination>().Combination;
        GetComponent<Button>().onClick.AddListener(Invoke);
    }

    public void Invoke()
    {
        Combination?.Invoke(transform.GetSiblingIndex());
    }

}

아이템 조합버튼은 현재 자신의 계층정보을 인덱스로 부모 UI의 메서드를 호출해준다.

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

public class UICombination : MonoBehaviour 
{
    List<RecipeSO> possibleRecipe;
    Image[] slot;

    private void Awake()
    {
        slot = new Image[5];
        for (int i =0; i< 5; i++)
        {
            slot[i] = transform.GetChild(i).GetComponent<Image>();
        }
        
    }

    public void UpdateUICombination()
    {
        possibleRecipe = CombinationManager.Instance.FindPossibleRecipe();

        foreach(Image image in slot)
        {
            image.gameObject.SetActive(false);
        }
        for (int i = 0; i < possibleRecipe.Count; i++) 
        {
            slot[i].sprite = possibleRecipe[i].combinationItem.GetComponent<Item>().itemSO.icon;
            
            slot[i].gameObject.SetActive(true);
        }
    }

    public void Combination(int index)
    {
        CombinationManager.Instance.Combination(possibleRecipe[index]);
    }


UICombination에서는 현재 찾은 가능한 레시피를 UI에 띄워주고 버튼에서 Index정보를 받아

CombinationManager의 메서드를 호출해서 조합을 진행시킨다.

nbcthumbnail



TIL내일배움캠프스파르타 Share Tweet +1