Chapter 9-4. 건축 : 건축 아이템 소모
Categories: Unity Lesson 3
Tags: Unity Game Engine
인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 - Advanced 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click
건축 시스템
🚀 건축 UI 필요한 아이템 텍스트
이런식으로 해당 슬롯의 건축물을 건축하기 위해서 필요한 아이템을 표시해줄 것이다. 텍스트 UI 를 슬롯들에 추가해준다.
📜CraftManual.cs
[System.Serializable]
public class Craft
{
public string craftName; // 이름
public Sprite craftImage; // 이미지
public string craftDescription; // 설명
public string[] craftNeedItem; // 필요한 아이템
public int[] craftNeedItemCount; // 필요한 아이템의 개수
public GameObject go_prefab; // 실제 설치 될 프리팹
public GameObject go_PreviewPrefab; // 미리 보기 프리팹
}
public class CraftManual : MonoBehaviour
{
[SerializeField]
private Text[] text_SlotNeedItem;
필요한 아이템 텍스트도 추가해주자. 필요한 아이템은 여러개일 수 있기 때문에 배열로 선언한다.
- 필요한 아이템
craftNeedItem
배열 - 필요한 아이템의 개수
craftNeedItemCount
배열- craftNeedItemCount[i]은 craftNeedItem[i] 아이템의 갯수가 들어간다.
이 텍스트를 표시할 4 개의 텍스트 UI 오브젝트들도 배열로 추가해주자.
- 모닥불 건축시 Leaf 3 개, Log 2 개 필요
- 토대 건축시 Log 2 개 필요
- 기둥 건축시 Log 1 개 필요
private void ClearSlot()
{
for (int i = 0; i < go_Slots.Length; i++)
{
image_Slot[i].sprite = null;
text_SlotName[i].text = "";
text_SlotDescription[i].text = "";
text_SlotNeedItem[i].text = "";
go_Slots[i].SetActive(false);
}
}
private void TabSlotSetting(Craft[] _craft_tab)
{
ClearSlot();
craft_SelectedTab = _craft_tab;
int startSlotNumber = (page - 1) * go_Slots.Length; // 4 의 배수
for (int i = startSlotNumber; i < craft_SelectedTab.Length; i++)
{
if (i == page * go_Slots.Length) // 슬롯 4 개 초과하지 않도록
break;
go_Slots[i - startSlotNumber].SetActive(true);
image_Slot[i - startSlotNumber].sprite = craft_SelectedTab[i].craftImage;
text_SlotName[i - startSlotNumber].text = craft_SelectedTab[i].craftName;
text_SlotDescription[i - startSlotNumber].text = craft_SelectedTab[i].craftDescription;
for (int j = 0; j < craft_SelectedTab[i].craftNeedItem.Length; j++)
{
text_SlotNeedItem[i - startSlotNumber].text += craft_SelectedTab[i].craftNeedItem[j];
text_SlotNeedItem[i - startSlotNumber].text += " x " + craft_SelectedTab[i].craftNeedItemCount[j] + "\n";
}
}
}
- ClearSlot()
- 아이템 설명 텍스트
text_SlotNeedItem
- 아이템 설명 텍스트
- TabSlotSetting(Craft[] _craft_tab)
- 건축물을 지을 때 필요한 아이템이 여러개일 수 있기 때문에
text_SlotNeedItem
에 텍스트 문자열 설정시 for문으로 돌려야 한다.아이템이 3 개라면 통나무 x 10 나뭇가지 x 5 나뭇잎 x 2 이렇게 3 줄로 나뉜 하나의 텍스트로서 들어가야 함.
for (int j = 0; j < craft_SelectedTab[i].craftNeedItem.Length; j++) { text_SlotNeedItem[i - startSlotNumber].text += craft_SelectedTab[i].craftNeedItem[j]; text_SlotNeedItem[i - startSlotNumber].text += " x " + craft_SelectedTab[i].craftNeedItemCount[j] + "\n"; // 한 줄 띄우기 }
- 건축물을 지을 때 필요한 아이템이 여러개일 수 있기 때문에
4 개의 필요한 아이템 텍스트 UI 오브젝트도 text_SlotNeedItem
배열에 할당해주기
🚀 건축 아이템 소모 처리
건축하면 그 건축할 때 소모되는 아이템을 인벤토리 혹은 퀵슬롯에 있는 아이템에서 차감해주어야 한다. 따라서 📜Inventory.cs 에서 public 함수를 만들어 적절하게 이를 호출할 수 있도록 함
📜Inventory.cs
public int GetItemCount(string _itemName)
{
int temp = SearchSlotItem(slots, _itemName);
return temp != 0 ? temp : SearchSlotItem(quickSlots, _itemName);
}
private int SearchSlotItem(Slot[] _slots, string _itemName)
{
for (int i = 0; i < _slots.Length; i++)
{
if (_slots[i].item != null)
{
if (_itemName == _slots[i].item.itemName)
return _slots[i].itemCount;
}
}
return 0;
}
public void SetItemCount(string _itemName, int _itemCount)
{
if (!ItemCountAdjust(slots, _itemName, _itemCount))
ItemCountAdjust(quickSlots, _itemName, _itemCount);
}
private bool ItemCountAdjust(Slot[] _slots, string _itemName, int _itemCount)
{
for (int i = 0; i < _slots.Length; i++)
{
if (_slots[i].item != null)
{
if (_itemName == _slots[i].item.itemName)
{
_slots[i].SetSlotCount(-_itemCount);
return true;
}
}
}
return false; // 인벤토리에 없어서 퀵슬롯에서 빼야 됨
}
- 먼저 현재 인벤토리 혹은 퀵슬롯에서 가지고 있는 아이템 갯수가 해당 건축물에 필요한 아이템 갯수보다 작으면 프리뷰를 생성하지 못하게 해야 한다. 즉 건축 슬롯 눌러도 건축 되지 않게끔 해야 한다. 따라서 인수로 받은 아이템이 현재 인벤토리 혹은 퀵슬롯에 몇개 있는지 확인해야 한다.
- GetItemCount
- 인수로 받은 아이템 이름과 일치하는 아이템이 인벤토리 혹은 퀵슬롯에 있다면 그 갯수를 리턴한다. 없다면 0 리턴
- 인벤토리 슬롯들에서 검사를 진행하고 SearchSlotItem(slots, _itemName)
- 없다면 SearchSlotItem(quickSlots, _itemName) 퀵슬롯 슬롯들에서 한번 더 검사 진행
- 인수로 받은 아이템 이름과 일치하는 아이템이 인벤토리 혹은 퀵슬롯에 있다면 그 갯수를 리턴한다. 없다면 0 리턴
- SearchSlotItem
- 인수로 받은 슬롯 배열에서 인수로 받은 이름과 일치하는 아이템을 찾는다.
- 찾았다면 그 아이템의 현재 갯수 리턴
- 없다면 0 리턴
- GetItemCount
- 건축물을 지었다면 인벤토리 혹은 퀵슬롯에서 보유중인 아이템 갯수에서 차감 처리를 해야 한다. 건축에 쓰인 갯수만큼!
- SetItemCount
- 인벤토리 슬롯들에서 검사를 진행하고 ItemCountAdjust(slots, _itemName, _itemCount) 없다면 ItemCountAdjust(quickSlots, _itemName, _itemCount) 퀵슬롯 슬롯들에서 한번 더 검사 진행
- ItemCountAdjust
- 인수로 받은 슬롯 배열에서 인수로 받은 이름과 일치하는 아이템을 찾는다.
- 찾았다면 그 아이템의 보유 갯수를 인수로 받은
_itemCount
만큼 차감하고 true 리턴 - 못 찾았다면 false 리턴
- SetItemCount
📜CraftManual.cs
// 필요한 컴포넌트
private Inventory theInventory;
void Start()
{
theInventory = FindObjectOfType<Inventory>();
tabNumber = 0;
page = 1;
TabSlotSetting(craft_fire);
}
📜Inventory 를 컴포넌트로 가져온다. 위에서 만든 public 함수들을 사용하기 위해서.
public void SlotClick(int _slotNumber)
{
selectedSlotNumber = _slotNumber + (page - 1) * go_Slots.Length;
if (!CheckIngredient())
return;
go_Preview = Instantiate(craft_SelectedTab[selectedSlotNumber].go_PreviewPrefab, tf_Player.position + tf_Player.forward, Quaternion.identity);
go_Prefab = craft_SelectedTab[selectedSlotNumber].go_prefab;
isPreviewActivated = true;
go_BaseUI.SetActive(false);
}
private bool CheckIngredient()
{
for (int i = 0; i < craft_SelectedTab[selectedSlotNumber].craftNeedItem.Length; i++)
{
if (theInventory.GetItemCount(craft_SelectedTab[selectedSlotNumber].craftNeedItem[i]) < craft_SelectedTab[selectedSlotNumber].craftNeedItemCount[i])
return false;
}
return true;
}
private void UseIngredient()
{
for (int i = 0; i < craft_SelectedTab[selectedSlotNumber].craftNeedItem.Length; i++)
{
theInventory.SetItemCount(craft_SelectedTab[selectedSlotNumber].craftNeedItem[i], craft_SelectedTab[selectedSlotNumber].craftNeedItemCount[i]);
}
}
private void Build()
{
if(isPreviewActivated && go_Preview.GetComponent<PreviewObject>().isBuildable())
{
UseIngredient();
Instantiate(go_Prefab, go_Preview.transform.position, go_Preview.transform.rotation);
Destroy(go_Preview);
isActivated = false;
isPreviewActivated = false;
go_Preview = null;
go_Prefab = null;
}
}
- SlotClick
- 현재 보유 아이템으로 클릭한 슬롯의 건축물을 지을 수 없다면 프리뷰를 짓지 못한다.
if (!CheckIngredient()) return;
- 현재 보유 아이템으로 클릭한 슬롯의 건축물을 지을 수 없다면 프리뷰를 짓지 못한다.
- CheckIngredient()
- 현재 선택된 탭의 선택된 슬롯이 필요한 아이템들은 여러개가 있을 수 있으므로 for문 돌려 다 검사
- 아이템 하나라도 갯수 모자르면 건축 못한다.
- 현재 선택된 탭의 선택된 슬롯이 필요한 아이템의 갯수보다 현재 보유 중인 아이템 갯수가 더 작으면 건축하지 못한다. false 리턴
- 📜Inventory의 GetItemCount 함수 사용
- 현재 선택된 탭의 선택된 슬롯이 필요한 아이템들은 여러개가 있을 수 있으므로 for문 돌려 다 검사
- UseIngredient()
- 건축시 실제 건축물에 필요한 아이템들의 인벤토리or퀵슬롯 차감 처리.
- 📜Inventory의 SetItemCount 함수 사용
- 건축시 실제 건축물에 필요한 아이템들의 인벤토리or퀵슬롯 차감 처리.
- Build()
- 건축시 UseIngredient() 호출하여 아이템 차감
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
Leave a comment