이번거는 많이 어렵다고 느낀다..
학교에서 내 생각대로 했었던 코드들은 뭔가 회생 불가능할 것 처럼 보여서
강사님의 코드를 보고 써보고 이해해보기로 하였다.
그래도 뭔가 많이 어렵다..
Test04Stages
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class Test04Stage : MonoBehaviour
{
public enum eState
{
Lock, Open, Complete
}
//텍스트
[SerializeField]
private TMP_Text[] arrTxtStageNum;
//Lock, Open, Complete GameObject
[SerializeField]
private GameObject[] arrStateGo;
//상태 저장
[SerializeField]
private eState state;
//밖에서 상태 쓰려고
public eState State
{
get
{
return this.state;
}
}
//Stage Image 사용하려고
private Button btn;
//대리자 사용해서 상태 가져오려고
public System.Action<int, eState> onClick;
//스테이지 숫자
private int stageNum;
//스테이지 숫자 가져오려고
public int StageNum
{
get
{
return this.stageNum;
}
}
//stageNum과 state(상태)를 받아오는 Init
public void Init(int stageNum, eState state)
{
//스테이지 숫자 받아와서 넣어주고
this.stageNum = stageNum;
Debug.Log(stageNum);
//버튼 할당 받아주고
this.btn = this.GetComponent<Button>();
// 텍스트에 스테이지 숫자 넣어준다
foreach(TMP_Text tmpText in this.arrTxtStageNum)
{
tmpText.text = stageNum.ToString();
}
//이미지를 클릭하면 대리자 실행
this.btn.onClick.AddListener(() => {
this.onClick(this.stageNum, this.state);
});
this.state = state;
this.ChangeState(this.state);
this.gameObject.SetActive(true);
}
public void ChangeState(eState state)
{
//모두 비활성화
this.InActiveAll();
//상태 받아주고
this.state = state;
//index에 그 상태 숫자값 넣기
int index = (int)this.state;
//그 상태의 숫자값 받은 애만 활성화 시켜주기
this.arrStateGo[index].SetActive(true);
}
//모두 비활성화
private void InActiveAll()
{
//하나씩 다 비활성화
foreach(GameObject go in this.arrStateGo)
{
go.SetActive(false);
}
}
public void Show()
{
this.gameObject.SetActive(true);
}
public void Hide()
{
this.gameObject.SetActive(false);
}
//UI에 업데이트하기
public void UpdateUI(int stageNum, eState state)
{
this.stageNum = stageNum;
this.state = state;
foreach(TMP_Text tmpText in this.arrTxtStageNum)
{
tmpText.text = stageNum.ToString();
}
this.ChangeState(this.state);
this.gameObject.SetActive(true);
}
}
Test04UIStageController
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class Test04UIStageController : MonoBehaviour
{
[SerializeField]
private Test04Stage[] stages;
private Dictionary<int, Test04Stage.eState> dic = new Dictionary<int, Test04Stage.eState>();
private int totalStages;
public event UnityAction onMoveNextEvent;
private Test04UIPageStage.Page page;
public void Init(int totalStages, Test04UIPageStage.Page page)
{
this.page = page;
Debug.LogFormat("[Init] {0} - {1}, total : {2}", this.page.start, this.page.end, this.page.Total);
this.totalStages = totalStages;
for(int i = 0; i < this.totalStages; i++)
{
var stageNum = i + 1;
if(stageNum == 1)
{
dic.Add(stageNum, Test04Stage.eState.Open);
}
else
{
dic.Add(stageNum, Test04Stage.eState.Lock);
}
}
this.Clear();
//이벤트 등록
for (int i = 0; i < this.page.Total; i++)
{
var uiStage = this.stages[i];
int idx = i;
uiStage.onClick = (stageNum, state) =>
{
Debug.LogFormat("stageNum: {0}, state: {1}", stageNum, state);
if (state != Test04Stage.eState.Open) return;
this.CompleteStage(uiStage);
int nextStageNum = stageNum + 1;
if (nextStageNum <= this.totalStages)
{
Debug.LogFormat("{0} ~ {1}, total : {2}", this.page.start, this.page.end, this.page.Total);
Debug.LogFormat("다음 스테이지 오픈 : {0}, page.end: {1}", nextStageNum, this.page.end);
//다음 Test04Stage가 현재 페이지에 있는지 확인
if (nextStageNum > this.page.end)
{
Debug.Log("다음 스테이지가 현재 페이지에 없음");
//데이터만 변경
this.dic[nextStageNum] = Test04Stage.eState.Open;
//다음 페이지로 이동 버튼 눌렀을 때 로직 실행
this.onMoveNextEvent();
}
else
{
Debug.Log("다음 스테이지가 현재 페이지에 있음");
Test04Stage nextUIStage = this.stages[idx + 1];
Debug.LogFormat("nextUIStage: {0}", nextUIStage);
//데이터를 변경하고
this.dic[nextStageNum] = Test04Stage.eState.Open;
//UI를 업데이트 함
nextUIStage.ChangeState(Test04Stage.eState.Open);
//모든 스테이지들의 상태를 출력
for (int i = 0; i < this.totalStages; i++)
{
var num = i + 1;
Debug.LogFormat("{0} : {1}", num, this.dic[num]);
}
}
}
else
{
Debug.Log("마지막 스테이지");
}
};
int stageNum = page.start + i;
uiStage.Init(stageNum, this.dic[stageNum]);
}
}
private void CompleteStage(Test04Stage uiStage)
{
if(uiStage.State == Test04Stage.eState.Open)
{
this.dic[uiStage.StageNum] = Test04Stage.eState.Complete;
//해당 스테이지 찾아 업데이트 하기
uiStage.ChangeState(Test04Stage.eState.Complete);
}
}
public void UpdateUI(Test04UIPageStage.Page page)
{
this.page = page;
Debug.LogFormat("[UpdateUI] {0} ~ {1}, total : {2}", this.page.start, this.page.end, this.page.Total);
for (int i = 0; i < this.totalStages; i++)
{
var stageNum = i + 1;
Debug.LogFormat("{0} : {1}", stageNum, this.dic[stageNum]);
}
this.Clear();
for (int i = 0; i < page.Total; i++)
{
var uiStage = this.stages[i];
int stageNum = page.start + i;
uiStage.UpdateUI(stageNum, this.dic[stageNum]);
}
}
private void Clear()
{
foreach (Test04Stage uiStage in this.stages)
{
uiStage.Hide();
}
}
}
Test04UIPageStage
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Test04UIPageStage : MonoBehaviour
{
public struct Page
{
public int start;
public int end;
public int Total
{
get
{
return this.end - this.start + 1;
}
}
public Page(int start, int end)
{
this.start = start;
this.end = end;
}
}
private const int MAX_DISPLAY_STAGES = 18; //한 페이지에 보여줄 수 있는 최대 스테이지 갯수
[SerializeField]
private Button btnPrev;
[SerializeField]
private Button btnNext;
[SerializeField]
private int totalStages = 28;
[SerializeField]
private Test04UIStageController stageController;
private int currentPage = 1;
private int totalPage = -1;
public void Init()
{
//계산하기
this.totalPage = Mathf.CeilToInt((float)this.totalStages / MAX_DISPLAY_STAGES);
Page page = this.CalcStartEnd();
this.stageController.onMoveNextEvent += OnMoveNextEventHandler;
this.stageController.Init(totalStages, page);
this.btnNext.onClick.AddListener(() => {
this.MoveNext();
});
this.btnPrev.onClick.AddListener(() => {
this.MovePrev();
});
}
private void OnMoveNextEventHandler()
{
this.MoveNext();
}
private void OnDisable()
{
this.stageController.onMoveNextEvent -= OnMoveNextEventHandler;
}
private void MovePrev()
{
if (this.currentPage == 1)
{
Debug.Log("첫 페이지 입니다.");
return;
}
this.currentPage -= 1;
Debug.LogFormat("currentPage: {0}", this.currentPage);
Page page = this.CalcStartEnd();
this.stageController.UpdateUI(page); //초기화
}
private void MoveNext()
{
if (this.currentPage == this.totalPage)
{
Debug.Log("마지막 페이지 입니다.");
return;
}
this.currentPage += 1;
Debug.LogFormat("currentPage: {0}", this.currentPage);
Page page = this.CalcStartEnd();
Debug.LogFormat("<color=lime>{0} ~ {1}, Total: {2}</color>", page.start, page.end, page.Total);
this.stageController.UpdateUI(page); //초기화
}
private Page CalcStartEnd()
{
Debug.LogFormat("총 스테이지 : {0}", this.totalStages);
Debug.LogFormat("마지막 페이지 : {0}", this.totalPage);
Debug.LogFormat("현재 페이지 : {0}", this.currentPage);
int end = this.currentPage * MAX_DISPLAY_STAGES;
int start = end - (MAX_DISPLAY_STAGES - 1);
//마지막 스테이지가 총 스테이지보다 같거나 클 경우
if(end >= this.totalStages)
{
end = this.totalStages;
}
return new Page(start, end);
}
}
Test04UIMain
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test04UIMain : MonoBehaviour
{
[SerializeField]
private Test04UIPageStage uiPageStage;
// Start is called before the first frame update
void Start()
{
this.uiPageStage.Init();
}
}
'유니티 심화 > 복습' 카테고리의 다른 글
[복습] LearnUGUI - Practice05 [Shop] 잘 몰라서 메모장에 적어놓고 연습 (0) | 2023.09.07 |
---|---|
[복습] LearnUGUI - Test05[Shop] (0) | 2023.09.07 |
[복습] LearnUGUI - Stage (0) | 2023.09.06 |
[복습]LearnUGUI - Button, Toggle (0) | 2023.09.05 |
[복습] 동기/ 비동기 (0) | 2023.08.31 |