2022. 2. 14. 18:35ㆍUnity3D/수업 내용
총 3가지의 재화를 구입할 수 있는 Shop 메뉴를 구현해보자.
우선 나는 재화 종류마다 팝업 창 오브젝트를 만들어 주어서,
버튼이 눌린상태 , 안눌린 상태 구분하는 코드를 생략했다.
덕분에 수작업은 조금 늘었지만, 할 게 줄어서 좋기도 하다.
전체적인 구조는 다음과 같다.
캔버스의 자식으로 3개의 팝업 창 오브젝트가 있고,
각 팝업 창은 스크롤뷰와 슬롯 프리팹을 가지고 있다.
팝업 창을 열면 팝업창 오브젝트가 자신의 스크롤뷰 안에 슬롯 프리팹을 생성한다.
실행 화면
소스 코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIShopControl : MonoBehaviour
{
[SerializeField] GameObject[] goPopUps;
bool[] isGen = new bool[3];
void Start()
{
isGen[0] = false;
isGen[1] = false;
isGen[2] = false;
}
public void ClosePopUp()
{
foreach (GameObject popUp in goPopUps)
{
popUp.SetActive(false);
}
}
public void OpenGoldPopUp()
{
foreach(GameObject popUp in goPopUps)
{
popUp.SetActive(false);
}
if (!isGen[0])
{
goPopUps[0].GetComponent<UIShopPopUpInfoControl>().InitPopUp(0);
isGen[0] = true;
}
goPopUps[0].SetActive(true);
}
public void OpenGemPopUp()
{
foreach (GameObject popUp in goPopUps)
{
popUp.SetActive(false);
}
if (!isGen[1])
{
goPopUps[1].GetComponent<UIShopPopUpInfoControl>().InitPopUp(1);
isGen[1] = true;
}
goPopUps[1].SetActive(true);
}
public void OpenSoulGemPopUp()
{
foreach (GameObject popUp in goPopUps)
{
popUp.SetActive(false);
}
if (!isGen[2])
{
goPopUps[2].GetComponent<UIShopPopUpInfoControl>().InitPopUp(2);
isGen[2] = true;
}
goPopUps[2].SetActive(true);
}
}
3개의 팝업창을 가지고 있는 캔버스의 스크립트다.
배열로 가지고 있으며,
슬롯을 인스턴스화해서 생성하는 작업은 처음 한번만 하기 위해
동일한 크기의 bool 배열을 만들었다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIShopPopUpInfoControl : MonoBehaviour
{
int type;
[SerializeField] GameObject goShopSlot;
[SerializeField] GameObject grid;
public void InitPopUp(int type)
{
this.type = type;
LoadShopSlot();
}
void LoadShopSlot()
{
Dictionary<int, ShopData> dict = DataManager.GetInstance().GetDictShopData();
List<ShopData> datas = new List<ShopData>();
foreach(ShopData data in dict.Values)
{
if(data.type == type)
{
datas.Add(data);
}
}
for(int i = 0; i < datas.Count; i++)
{
GameObject go = Instantiate(goShopSlot);
go.transform.SetParent(grid.transform);
go.GetComponent<UIShopSlotControl>().InitShopSlot(datas[i].id);
}
}
}
각각의 팝업창이 가지고 있는 스크립트다.
이전의 캔버스 스크립트에서 InitPopUp()메서드를 통해 이곳으로 흘러들어오게 된다.
그리고 LoadShopSlot()메서드를 통해 슬롯프리팹이 가지고 있는 스크립트로 넘어가게 된다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.U2D;
public class UIShopSlotControl : MonoBehaviour
{
int id;
[SerializeField] SpriteAtlas atlas;
[SerializeField] Image icon;
[SerializeField] Text rewardText;
[SerializeField] Text bonusText;
[SerializeField] Image purchaseIcon;
[SerializeField] Text purchaseText;
public void InitShopSlot(int id)
{
this.id = id;
LoadSlotInfo();
}
void LoadSlotInfo()
{
ShopData data = DataManager.GetInstance().GetShopData(id);
this.icon.sprite = atlas.GetSprite(data.spriteName);
this.icon.SetNativeSize();
this.rewardText.text = string.Format("{0:#,###}", int.Parse(data.name));
if (data.bonus > 0)
{
this.bonusText.text = "bonus +" + data.bonus + "%";
}
else
{
this.bonusText.gameObject.SetActive(false);
}
this.purchaseIcon.sprite = atlas.GetSprite(DataManager.GetInstance().GetBudgetData(data.budget_id).spriteName);
this.purchaseIcon.SetNativeSize();
this.purchaseText.text = data.price;
}
}
최종적으로 이 곳에서 팝업창의 모든 정보를 표기해준다.
피드백
- 캔버스 스크립트에서 같은 기능의 함수를 중복해서 만들었는데, 이럴 거면 굳이 팝업창을 3개 만들지 않아도 될 것 같다는 생각이 들었다.
이 코드의 장점은 팝업창이 재화 종류별로 있어서 처음 인스턴스화 하고 난 후에는
오브젝트 활성/비활성화로 간단하고 빠르게 각 팝업창을 키고 닫을 수 있다는 것이다.
그러나 이 장점은 굳이 팝업창을 종류별로 만들지 않고도 얻을 수 있는 다른 방법이 있다.
예를 들어 생성한 슬롯프리팹들을 리스트에 담아놓고,
다른 재화의 팝업창으로 이동할 때는 그 재화의 타입과 동일한 슬롯프리팹만 활성화시키고 나머지는
비활성화 시켜둔다던지 하는 식으로 말이다.
다음엔 이 방법으로 해보자.
'Unity3D > 수업 내용' 카테고리의 다른 글
22.02.18 애니메이션 이벤트, HUD 텍스트 표기하기 (0) | 2022.02.20 |
---|---|
22.02.15 업적 창 구현하기 (0) | 2022.02.15 |
22.02.11 UI 기능 추가 (페이지, 해금, 재화 표시) (0) | 2022.02.11 |
22.02.04 JSON 데이터를 UI에 바인딩하기 (0) | 2022.02.05 |
22.02.03 Canvas와 UI 배우기 (0) | 2022.02.03 |