본문 바로가기
KDT/유니티 심화

23/09/06 LearnUGUI (Stage 2)

by 잰쟁 2023. 9. 6.
728x90

1단계

처음 실행하면

1번 Stage : Doing 상태

2~18번 Stage의 state : Lock 상태

클릭하면 StageNum과 state 출력하기

 

 

 

**오류 발생!

1번 UIStage만 눌렀을 때 콘솔이 나오지 않았다

=> 알고보니 UIStage에만 Button이 붙어져 있는게 아니라 그 아래 lock,doing,complete에도 Button이 붙어져 있었다.

Button떼어내니 잘 나온다ㅎㅎ

 

 

UIStage

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;

public class UIStage : MonoBehaviour
{
    public enum eState 
    { 
        Lock, Doing, Complete
    }

    [SerializeField]
    private TMP_Text[] arrTxtStageNum;

    [SerializeField]
    private GameObject[] arrStateGo;  //0: lock, 1: doing, 2: complete

    private eState state;
    private Button btn;
    private int stageNum;
    public System.Action<int, eState> onClick;

    //입력 받은 숫자를 텍스트로 나타내기(번호 부여) / 초기화
    public void Init(int stageNum)
    {
        this.stageNum = stageNum;
        this.btn = this.GetComponent<Button>();

        foreach(TMP_Text tmpText in this.arrTxtStageNum)
        {
            //숫자로 입력된 값을 문자열로 바꾸기
            tmpText.text = stageNum.ToString();
        }
        //Lock 상태로 상태 변화하기
        this.ChangeState(eState.Lock);

        //버튼을 누르면
        this.btn.onClick.AddListener(() => 
        {
            //대리자 사용하여 stageNum, state 넘기기..?
            this.onClick(this.stageNum, this.state);
        });
    }

    //모든 스테이지 비활성화
    private void InActiveAll()
    {
        foreach(var go in this.arrStateGo)
        {
            go.SetActive(false);
        }
    }

    //스테이지 상태 변경
    public void ChangeState(eState state)
    {
        //모두 비활성화 시킨 후
        this.InActiveAll();

        //상태를 받아서 그 상태를 활성화 시키기
        this.state = state;
        int index = (int)this.state;
        this.arrStateGo[index].SetActive(true);
    }
}

UIStageController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test04UIStageController : MonoBehaviour
{
    [SerializeField]
    private UIStage[] uiStages;


    public void Init()
    {
        for(int i =0; i < this.uiStages.Length; i++)
        {
            var uiStage = this.uiStages[i];
            //대리자 받아와서 stageNum, state 출력하기
            uiStage.onClick = (stageNum, state) =>
            {
                Debug.LogFormat("stageNum: {0}, state: {1}", stageNum, state);
            };
            //stageNum 1씩 증가하기
            int stageNum = i + 1;
            //UIStage 초기화
            uiStage.Init(stageNum);
        }
        //첫번째 UIStage 상태 doing으로 변환
        this.uiStages[0].ChangeState(UIStage.eState.Doing);
    }
}

UIPageStage

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test04UIPageStage : MonoBehaviour
{
    //한페이지에 보여줄 수 있는 최대 스테이지 갯수 (상수)
    private const int MAX_DISPLAY_STAGES = 18;

    [SerializeField] private int totalStages = 28;  //총 스테이지 개수
    [SerializeField] private Button btnPrev;  //이전 버튼
    [SerializeField] private Button btnNext;  //다음 버튼
    [SerializeField] private Test04UIStageController stageController;  //UIStage들 관리하는 컴포넌트

    private int currentPageNum = 1;  //현재 페이지 넘버

    public void Init()
    {
        //초기화
        this.stageController.Init();
    }
}

UIMain

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test04UIMain : MonoBehaviour
{
    [SerializeField]
    private Test04UIPageStage uIPageStage;

    private void Start()
    {
        //초기화
        this.uIPageStage.Init();
    }
}

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;

public class UIStage : MonoBehaviour
{
    public enum eState 
    { 
        Lock, Doing, Complete
    }

    [SerializeField]
    private TMP_Text[] arrTxtStageNum;

    [SerializeField]
    private GameObject[] arrStateGo;  //0: lock, 1: doing, 2: complete

    private eState state;
    private Button btn;
    private int stageNum;
    public System.Action<int, eState> onClick;

    //입력 받은 숫자를 텍스트로 나타내기(번호 부여) / 초기화
    public void Init(int stageNum)
    {
        this.stageNum = stageNum;
        this.btn = this.GetComponent<Button>();

        foreach(TMP_Text tmpText in this.arrTxtStageNum)
        {
            //숫자로 입력된 값을 문자열로 바꾸기
            tmpText.text = stageNum.ToString();
        }
        //Lock 상태로 상태 변화하기
        this.ChangeState(eState.Doing);

        //버튼을 누르면
        this.btn.onClick.AddListener(() => 
        {
            //대리자 사용하여 stageNum, state 넘기기..?
            this.onClick(this.stageNum, this.state);
        });
    }

    //모든 스테이지 비활성화
    private void InActiveAll()
    {
        foreach(var go in this.arrStateGo)
        {
            go.SetActive(false);
        }
    }

    //스테이지 상태 변경
    public void ChangeState(eState state)
    {
        //모두 비활성화 시킨 후
        this.InActiveAll();

        //받은 상태를 활성화시키기
        this.state = state;
        int index = (int)this.state;
        this.arrStateGo[index].SetActive(true);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test04UIStageController : MonoBehaviour
{
    [SerializeField]
    private UIStage[] uiStages;


    public void Init()
    {
        for(int i =0; i < this.uiStages.Length; i++)
        {
            var uiStage = this.uiStages[i];
            //대리자 받아와서 stageNum, state 출력하기
            uiStage.onClick = (stageNum, state) =>
            {
                Debug.LogFormat("stageNum: {0}, state: {1}", stageNum, state);
            };
            //stageNum 1씩 증가하기
            int stageNum = i + 1;
            //UIStage 초기화
            uiStage.Init(stageNum);
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;

public class Test04UIPageStage : MonoBehaviour
{
    //한페이지에 보여줄 수 있는 최대 스테이지 갯수 (상수)
    private const int MAX_DISPLAY_STAGES = 18;

    [SerializeField] private int totalStages = 28;  //총 스테이지 개수
    [SerializeField] private Button btnPrev;  //이전 버튼
    [SerializeField] private Button btnNext;  //다음 버튼
    [SerializeField] private Test04UIStageController stageController;  //UIStage들 관리하는 컴포넌트

    private int firstPageNum = 1;
    private int currentPageNum = 1;  //현재 페이지 넘버
    private int lastPageNum;
    private int startNum;  //페이지 시작 넘버
    private int endNum;  //페이지 끝 넘버
    private int currStageAmount;  //현재 페이지의 스테이지 개수

    private void Start()
    {
        
    }

    public void Init()
    {
        //계산하기
        //마지막페이지 넘버(올림으로 구하기)
        this.lastPageNum = Mathf.CeilToInt((float)this.totalStages / MAX_DISPLAY_STAGES);
        this.endNum = this.currentPageNum * MAX_DISPLAY_STAGES;
        this.startNum = this.endNum - (MAX_DISPLAY_STAGES - 1);
        this.currStageAmount = (this.endNum - this.startNum) + 1;

        //처음 실행하면 첫 페이지 값 출력
        this.Print();

        //초기화
        this.stageController.Init();

        //Next 버튼 누르면
        this.btnNext.onClick.AddListener(() =>
        {
            this.GoNext();
        });

        //Prev 버튼 누르면
        this.btnPrev.onClick.AddListener(() =>
        {
            this.GoPrev(); 
        });
    }

    private void GoNext()
    {
        //페이지 더해주기
        this.currentPageNum++;
        if (this.currentPageNum > this.lastPageNum)
        {
            Debug.Log("마지막 페이지입니다.");          
        }
        else
        {
            Debug.Log("다음 페이지입니다.");
            this.Print();
        }
    }

    private void GoPrev()
    {
        //페이지 빼주기
        this.currentPageNum--;
        if (this.currentPageNum < this.firstPageNum)
        {
            Debug.Log("첫 페이지입니다.");
            
        }
        else
        {
            Debug.Log("이전 페이지입니다.");
            this.Print();
        }
    }

    //페이지 정보 출력하기
    private void Print()
    {
        Debug.LogFormat("총 스테이지 : {0}", this.totalStages);
        Debug.LogFormat("마지막 페이지 : {0}", this.lastPageNum);
        Debug.LogFormat("현재 페이지 : {0}", this.currentPageNum);
        //현재 페이지가 마지막 페이지이면
        if(this.currentPageNum == this.lastPageNum)
        {
            Debug.LogFormat("{0} ~ {1}, total:{2}", this.startNum, this.totalStages,(this.totalStages - this.startNum +1));
        }
        else 
        {
            Debug.LogFormat("{0} ~ {1}, total:{2}", this.startNum, this.endNum, this.currStageAmount);
        }
        
    }
}