[UGUI연습] 스테이지 클리어 창 만들기
구현내용
-한 줄에 6개 씩 표시하므로 한 페이지에 표시되는 개수는 18개
=> 2페이지로 구현(총 28개의 스테이지가 있고 가정)
=> 이번페이지 버튼, 다음페이지 버튼 추가
-UIStage의 상태 : Lock, Doing, Complete
-닫기 버튼(팝업)
-뒤로가기 버튼(페이지)
-현재 페이지를 저장 해놔야함. 이전 페이지를 누르면 현재페이지 -1, 다음 페이지는 현재 페이지 +1
-1페이지일때는 이전 페이지로 가는 버튼이 보이면 안된다.
-마찬가지로 마지막 페이지일 경우 다음 페이지 버튼이 보이면 안된다.
Test04를 만들어준다.
-grid까지 만들고 grid에 grid layout Group 컴포넌트 추가
-UIStage를 프리팹으로 만들고 Object Pooling 해서 가져오려 한다.
-시작할때 오브젝트 풀을 생성해서 비활성화시켜둔다.(UIStagePool()메서드)
-필요할때마다 active해서 사용한다. 이 구현의 경우 시작할때 첫페이지는 꽉 차있으므로 전부 active시켜주기 위해 InitUIStage()메서드를 호출했다.
다음 스테이지로 넘어가는 버튼을 눌렀을 때 첫번째 페이지의 정보를 저장해둘 곳이 필요했다.
이를 멤버 변수로 저장하며,
UpdatePage()메서드를 통해 불러오도록했다.
+) 아직 코드를 수정해야 한다. 피곤해서 여기까지ㅜㅜ
1. 다음 페이지 넘어갔을때 숫자 초기화 되지 않고 받아오기
2. 다음 페이지의 인덱스,상태도 저장하기
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class Test04UIStage : MonoBehaviour
{
public enum eState{
Lock,Doing,Complete
}
[SerializeField] private TMP_Text[] arrTxtStageNum;
[SerializeField] private GameObject[] arrStateGo; //0: lock, 1: doing, 2: complete
public eState state;
public void Init(int stageNum)
{
foreach (var tmpText in this.arrTxtStageNum)
{
tmpText.text = (stageNum+1).ToString();
}
this.InActiveAll();
this.ChangeState(eState.Lock);
}
public void ChangeState(eState state)
{
this.state = state;
int index = (int)this.state;
this.InActiveAll();
this.arrStateGo[index].SetActive(true);
}
private void InActiveAll()
{
foreach (var go in this.arrStateGo)
{
go.SetActive(false);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System;
public class Test04UIMain : MonoBehaviour
{
[SerializeField] private Button btnPrev;
[SerializeField] private Button btnNext;
[SerializeField] private TextMeshProUGUI textMesh;
[SerializeField] private Test04UIStageController stageController;//1페이지
// private List<Test04UIStageController> stageControllers;
private int currPageNum = 1;//현재페이지 번호
public int lastPageNum = 2;//마지막 페이지 번호
private int stageNum;
private int maxStageNum = 20;
private Action onPrevStage;
private Action onNextStage;
// Start is called before the first frame update
void Start()
{
// Debug.Log(this.stageController.uiStages.Count);
this.btnPrev.onClick.AddListener(() => {
if (this.currPageNum>0) {
this.currPageNum--;
this.onPrevStage();
}
});
this.btnNext.onClick.AddListener(() => {
if (this.currPageNum < this.lastPageNum)
{
this.currPageNum++;
this.onNextStage();
// this.stageController.onClearpage();
}
});
this.onPrevStage = () =>
{
Debug.Log("이전페이지로 이동");
this.stageController.UpdatePage();
//this.stageController.gameObject.SetActive(true);
// this.stageController2.gameObject.SetActive(false);
};
this.onNextStage = () =>
{
Debug.Log("다음페이지로 이동");
this.stageController.UnActivatePrevPage();
this.stageController.InitUIStage();
// this.stageController.InitUIStage();
//update
};
}
// Update is called once per frame
void Update()
{
this.textMesh.text = string.Format("{0}/{1}", this.currPageNum, this.lastPageNum);
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using UnityEngine;
using UnityEngine.UI;
public class Test04UIStageController : MonoBehaviour
{
private List<Test04UIStage> uiStages = new List<Test04UIStage>();
public List<GameObject> uiPools = new List<GameObject>();
private List<Button> buttonList = new List<Button>();
[SerializeField] Test04UIMain main;
public System.Action onClearpage;
[SerializeField] GameObject UIStageGo;
[SerializeField] GameObject gridGo;
public int stageNum;
private int totalStageNum = 28;//총 스테이지 수
private int maxStageNum = 18;//한페이지 최대 수용량
private int maxPageNum;//페이지 수
private Test04UIStage.eState firstPageState;
private int firstPageIndex;
// Start is called before the first frame update
void Start()
{
this.UIStagePool();//오브젝트 풀 생성
//한 페이지 최대 수용량만큼 스테이지 생성
//총 스테이지 수 == 페이지 수 * 한 페이지 최대 수용량 + 총스테이지 수%한페이지 수용량
// 페이지 수 == 총 스테이지 수/ 한 페이지 최대 수용량
//maxPageNum == totalStageNum/ maxStageNum
//즉 총 스테이지 개수/페이지수 == 한 페이지의 스테이지 수이므로
//Debug.Log((totalStageNum / maxStageNum)+1);
this.maxPageNum = totalStageNum / maxStageNum + 1;
Debug.Log(maxPageNum);
Debug.Log(totalStageNum %maxStageNum);
this.InitUIStage();
if (this.stageNum == 0)
{
for (int i = 0; i < this.uiStages.Count; i++)
{
this.uiStages[i].Init(i);//시작 시 전부 lock
}
}
for(int i = 0; i < buttonList.Count; i++)
{
int index = i;
this.buttonList[i].onClick.AddListener(() =>
{
// Debug.Log("Click!");
this.firstPageState = this.checkState(index);
this.firstPageIndex = index;
});
}
}
public void InitUIStage()
{
for (int i = 0; i < this.maxStageNum; i++)
{
GameObject go = this.GetUIStageInPool();
go.SetActive(true);
this.uiStages.Add(go.GetComponent<Test04UIStage>());
this.uiStages[i].ChangeState(Test04UIStage.eState.Lock);//락 상태로 초기화
// Debug.Log(this.uiStages[i]);
this.buttonList.Add(go.GetComponent<Button>());
}
}
public void UnActivatePrevPage()
{
for (int i = 0; i < this.maxStageNum; i++)
{
GameObject go = this.uiPools[i];
go.SetActive(false);
}
}
public void UpdatePage()
{
//state = this.state;
//index = this.index;
for (int i = 0; i < this.maxStageNum; i++)
{
GameObject go = this.uiPools[i];
go.SetActive(true);
if (this.firstPageIndex == i)//멤버 변수에 저장된 index일때. 즉 클릭한 인덱스
{
if (i != 0 && this.firstPageState != Test04UIStage.eState.Lock)
{
for (int j = i - 1; j >=0; j--)
{//Doing인 인덱스 앞의 인덱스들의 경우 쭉 Complete로 만들어준다.
this.uiStages[j].ChangeState(Test04UIStage.eState.Complete);
}
}
else if (i != 0 && this.firstPageState == Test04UIStage.eState.Lock)
{
this.uiStages[i - 1].ChangeState(Test04UIStage.eState.Doing);
}
this.uiStages[i].ChangeState(this.firstPageState);//해당 index 상태 변경
Debug.Log(this.uiStages[i].state);
}
}
}
private void UIStagePool()
{
for (int i = 0; i < this.maxStageNum; i++)
{//스테이지 생성- 리스트에 담기
GameObject go = Instantiate<GameObject>(this.UIStageGo,this.gridGo.transform);
go.SetActive(false); //생성 후 비활성화 해둔다.
this.uiPools.Add(go);
// this.uiStages.Add(go.GetComponent<Test04UIStage>());
}
}
private GameObject GetUIStageInPool()
{
foreach(GameObject go in this.uiPools)
{
if (go.active == false)//비활성화 상태이면
{
return go;
}
}
return null;
}
private Test04UIStage.eState checkState(int index)
{
//Debug.Log("CheckState");
for (int i = 0; i < this.uiStages.Count; i++)
{
if(i== index)
{
if (this.uiStages[index].state == Test04UIStage.eState.Lock)
{//lock 상태면 doing으로 변환
if (index == 0)
{
this.uiStages[index].ChangeState(Test04UIStage.eState.Doing);
return Test04UIStage.eState.Doing;
}
else
{
if (this.uiStages[i - 1].state != Test04UIStage.eState.Doing)
{//lock이고 이전 스테이지를 완료했다면
this.uiStages[index].ChangeState(Test04UIStage.eState.Doing);
return Test04UIStage.eState.Doing;
}
else
{
Debug.Log("이전 스테이지 미완료");
return Test04UIStage.eState.Lock;
}
}
}
else if (this.uiStages[index].state == Test04UIStage.eState.Doing)
{//doing 상태면 complete로 변환
this.uiStages[index].ChangeState(Test04UIStage.eState.Complete);
return Test04UIStage.eState.Complete;
if (index == this.uiStages.Count-1)
{
Debug.Log("last stage clear");
//if (this.stageNum <2)
//{ this.onClearpage(); }
}
}
}
}
return Test04UIStage.eState.Lock;
}
}
'유니티 심화' 카테고리의 다른 글
[UGUI연습]-동적 스크롤 뷰, json연결 (0) | 2023.09.07 |
---|---|
[UGUI연습]스크롤 뷰 생성(정적 스크롤뷰) (0) | 2023.09.07 |
[UGUI연습] Stage-Complete,Doing,Lock(+Horizontal Layout Group) (0) | 2023.09.05 |
[UGUI연습]- InputField, PopUpName (0) | 2023.09.05 |
[UGUI 연습] LearnUGUI- Closure,캡처/ 토글 버튼 생성, CheckBox, Tab, UISlider (0) | 2023.09.04 |