오늘 배운 내용
- 팀 프로젝트 아이템, 인벤토리 구현
팀 프로젝트 아이템 조합 기능 구현
이제 아이템 조합 기능을 만들 차례다 일단 아이템조합 정보에 대한 것들을 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의 메서드를 호출해서 조합을 진행시킨다.