2022. 2. 9. 19:17ㆍUnity3D/수업 과제
[게임 상의 데이터 흐름]
UI의 본질은 유저에게 정보를 보여주는 수단이다.
이하 수업 과제
※ 유저가 스테이지 버튼이나 인벤토리 버튼 중 하나를 클릭했을 때,
해당 버튼의 스테이지 id나 아이템의 id를 조회하기 위해서
상위 부모 오브젝트의 스크립트에서 하위 오브젝트들의 배열을 순회하며 'Init()'을 해주었다.
( Init() : 하위 오브젝트가 갖고 있는 id 속성에 값을 부여해주는 메서드. )
※ 씬마다 게임매니져가 있어서 씬 내의 모든 UI캔버스들의 연결고리가 된다.
스테이지 씬에서는
그리드에 속한 오브젝트들을 활성/비활성화 하는 식으로 별 개수를 보여주었다.
팝업창의 무기 아이콘들도 마찬가지로 하였다.
그리고 스테이지에 대한 정보를 담은 팝업 창이 나오면
유저는 플레이하면서 사용할 아이템을 선택할 수 있다.
즉, 유저가 선택한 아이템에 체크 표시를 해야 하고,
Start가 눌리면 선택된 아이템이 인벤토리에서 개수가 차감되어야 한다.
어떤 구조로 만들어야 좋을지 고민하다가 시간을 가장 많이 날렸던 부분이다.
과정을 세분화해서 복습하자
유저가 아이템을 사용하기 위해 아이콘을 클릭했을 때
체크 표시를 하기 위해서
- 각 아이템 아이콘 이미지에 버튼을 부여한다.
- UI팝업인포컨트롤 스크립트에 체크 표시 아이콘을 담은 게임오브젝트 배열을 만든다.
- 버튼이 눌렸을 때 텍스트는 비활성화하고 체크 이미지를 활성화하도록 한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIPopUpInfoControl : MonoBehaviour
{
public Text stageNameText;
public Text missionNameText;
[SerializeField] Button btnStart;
public Image[] availItemImage = new Image[3]; //에디터 상에서 버튼 부여했음.
public GameObject[] availItemAmountText = new GameObject[3];
public GameObject[] itemCheckIcon = new GameObject[3]; //체크 아이콘들을 담음.
int index;
void Start()
{
InitImgBtn();
}
void InitImgBtn()
{
for (int i = 0; i < availItemImage.Length; i++)
{
GiveIndexToImgBtn(i);
}
}
void GiveIndexToImgBtn(int index)
{
availItemImage[index].GetComponent<Button>().onClick.AddListener(() =>
{
if (availItemAmountText[index].gameObject.activeSelf)
{
itemCheckIcon[index].gameObject.SetActive(true);
availItemAmountText[index].gameObject.SetActive(false);
}
else
{
itemCheckIcon[index].gameObject.SetActive(false);
availItemAmountText[index].gameObject.SetActive(true);
}
});
}
}
다음으로는 체크 표시된 아이템, 유저가 선택한 아이템의 id를 알아내서
Start가 눌렸을 때 그 id에 해당하는 아이템의 개수를 유저 인벤토리에서 차감시켜야 한다.
선택된 아이템의 id를 알아내기
- 팝업인포컨트롤 스크립트에 아이템Id를 담을 배열 3칸을 만든다. (배열)
- 팝업인포창을 띄우는 매개체인 UI슬롯컨트롤의 ShowPopUpInfo()메서드에서 아이템 아이콘 이미지를 할당해줄 때 1번에서 만든 배열에도 id를 할당해준다.
- 팝업인포컨트롤 스크립트에 선택된 아이템의 id만을 담을 동적배열을 만든다.
- 동적배열에 선택된 아이템의 id가 할당되는 코드를 위에서 체크표시를 하기 위해 만든 메서드 GiveIndexToImgBtn()에 몇 줄 추가해준다.
-
그럼 선택한 아이템의 id가 리스트에 정상적으로 추가된다.using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class UIPopUpInfoControl : MonoBehaviour { public Text stageNameText; public Text missionNameText; public Image[] availItemImage = new Image[3]; public GameObject[] availItemAmountText = new GameObject[3]; [SerializeField] GameObject[] itemCheckIcon = new GameObject[3]; [SerializeField] Button btnStart; [HideInInspector] public int[] itemIds = new int[3]; List<int> selectedItemIds = new List<int>(); void Start() { InitImgBtn(); } void InitImgBtn() { for (int i = 0; i < availItemImage.Length; i++) { GiveIndexToImgBtn(i); } } void GiveIndexToImgBtn(int index) { availItemImage[index].GetComponent<Button>().onClick.AddListener(() => { if (availItemAmountText[index].gameObject.activeSelf) { selectedItemIds.Add(itemIds[index]); itemCheckIcon[index].gameObject.SetActive(true); availItemAmountText[index].gameObject.SetActive(false); } else { selectedItemIds.Remove(itemIds[index]); itemCheckIcon[index].gameObject.SetActive(false); availItemAmountText[index].gameObject.SetActive(true); } foreach(int num in selectedItemIds) { Debug.Log("선택된 아이템의 id는 " + num); } } ); } public void ClosePopUpInfo() { for(int k = 0; k < itemCheckIcon.Length; k++) { itemCheckIcon[k].SetActive(false); availItemAmountText[k].SetActive(true); } selectedItemIds.RemoveRange(0, selectedItemIds.Count); gameObject.SetActive(false); } }
마지막으로, Start 버튼을 눌렀을 때 인벤토리에서 실제로 아이템의 개수가 차감되도록 하자.
선택된 아이템의 id에 해당하는 아이템 찾아서 사용하기
- 스타트 버튼이 눌렸을 때 인벤토리에서 id와 동일한 아이템을 찾아 사용하는 메서드를 AddListener한다.
- 그리고 아이템이 없을 때는 사용하지 못하게 위에 체크 표시를 담당하는 메서드에서 아이템 갯수를 파악하고 0개 이하면 체크가 되지 않도록 한다. (리스트에 id가 추가되지 못하게 한다.)
-
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class UIPopUpInfoControl : MonoBehaviour { public Text stageNameText; public Text missionNameText; public Image[] availItemImage = new Image[3]; public GameObject[] availItemAmountText = new GameObject[3]; [SerializeField] GameObject[] itemCheckIcon = new GameObject[3]; [SerializeField] Button btnStart; [HideInInspector] public int[] itemIds = new int[3]; List<int> selectedItemIds = new List<int>(); void Start() { InitImgBtn(); InitStartBtn(); } void InitStartBtn() { btnStart.onClick.AddListener(GetStarted); } void GetStarted() { for(int t = 0; t < selectedItemIds.Count; t++) { DataManager.GetInstance().UseItem(selectedItemIds[t]); } ResetUISettings(); } void InitImgBtn() { for (int i = 0; i < availItemImage.Length; i++) { GiveIndexToImgBtn(i); } } void GiveIndexToImgBtn(int index) { availItemImage[index].GetComponent<Button>().onClick.AddListener(() => { if (availItemAmountText[index].gameObject.activeSelf) { if(DataManager.GetInstance().GetItemInfoAmount(itemIds[index]) > 0) { selectedItemIds.Add(itemIds[index]); itemCheckIcon[index].gameObject.SetActive(true); availItemAmountText[index].gameObject.SetActive(false); } else { Debug.Log("해당 아이템을 갖고 있지 않습니다."); } } else { selectedItemIds.Remove(itemIds[index]); itemCheckIcon[index].gameObject.SetActive(false); availItemAmountText[index].gameObject.SetActive(true); } foreach(int num in selectedItemIds) { Debug.Log("선택된 아이템의 id는 " + num); } } ); } public void ClosePopUpInfo() { ResetUISettings(); gameObject.SetActive(false); } void ResetUISettings() { for (int k = 0; k < itemCheckIcon.Length; k++) { itemCheckIcon[k].SetActive(false); availItemAmountText[k].SetActive(true); } selectedItemIds.RemoveRange(0, selectedItemIds.Count); for(int n = 0; n < itemIds.Length; n++) { if(itemIds[n] != 0) { availItemAmountText[n].GetComponentInChildren<Text>().text = DataManager.GetInstance().GetItemInfoAmount(itemIds[n]) + ""; } } } }
-
public class DataManager { GameInfo gi; public void UseItem(int id) { foreach (ItemInfo info in gi.inventory) { if (info.id == id) { info.count--; return; } } } }
- 실행 결과
핵심은 선택한 슬롯의 인덱스를 받아오는 것이다.
나는 처음 버튼을 생성할 때 OnClick.AddListener로
버튼마다 어느 인덱스를 반환해야 하는지 설정해주었다.
그 인덱스로 아이템id 조회, 체크 표시 등등 전부 그 인덱스에 맞춰 코드를 짰기 때문에
인덱스만 알면 다 할 수 있었다.
'Unity3D > 수업 과제' 카테고리의 다른 글
22.01.26 논스톱 나이트 모작하기 (0) | 2022.01.26 |
---|---|
22.01.20 MiniTest (0) | 2022.01.20 |
22.01.19 Cat Escape Two (0) | 2022.01.19 |
22.01.18 Cat Escape 피하기 게임 만들기 (0) | 2022.01.18 |
22.01.17 [홈워크] 표창 던지기 (0) | 2022.01.17 |