EasyCastleUNITY

유니티 GUI 2 본문

유니티 심화

유니티 GUI 2

EasyCastleT 2023. 9. 5. 11:44

UI PopUp

팝업창의 모습

1. 닉네임을 입력하면, 노란색 버튼이 활성화된다. (회색 버튼 비활성화)

2. 노란색 버튼을 누르면 콘솔 창에 입력된 닉네임을 출력한다. 

3. 닉네임을 입력하지 않고, 회색 버튼을 누르면, text가 나오면서 닉네임을 입력하라고 한다.

4. 닉네임을 입력하고 노란색 버튼을 누르면 나왔던 주의문은 사라진다. 

5. 입력값이 없어지면, 노란색 버튼 비활성화, 회색 버튼 활성화 

팝업창 계층구조
InputField가 중요

Placeholder가 아무런 입력값도 없을 때, 사용자에게 보여주는 Text

Text가 사용자가 실제로 입력하는 Text

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

public class Test02UIPopName : MonoBehaviour
{
    [SerializeField] private TMP_InputField input;
    [SerializeField] private TMP_Text stateText;
    [SerializeField] private Button OffButton;
    [SerializeField] private Button OnButton;
    // Start is called before the first frame update
    void Start()
    {
        this.OnButton.onClick.AddListener(() => {
            this.stateText.text = "";
            Debug.LogFormat("<color=yellow>Nickname: {0} </color>", input.text);
        });
        this.OffButton.onClick.AddListener(() =>
        {
            this.stateText.text = "Please Input your Nickname";
        });

        this.input.onValueChanged.AddListener((str) => {
            if (str == "")
            {
                this.OffButton.gameObject.SetActive(true);
                this.OnButton.gameObject.SetActive(false);
            }
            else if (str != "")
            {
                this.OffButton.gameObject.SetActive(false);
                this.OnButton.gameObject.SetActive(true);
            }
        });
    }
}

실행 영상

동적으로 팝업창 만들기 

홈 캔버스 계층구조

빨간색 박스로 표시되어 있는 NickName Change 버튼을 누르면 팝업창이 생성된다. 

메인 캔버스에서 동작하는 스크립트

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

public class Test02HomeNickChange : MonoBehaviour
{
    private Button nickChangeButton;
    [SerializeField] private GameObject nicknameChangePopupPrefab;
    // Start is called before the first frame update
    void Start()
    {
        this.nickChangeButton = this.GetComponentInChildren<Button>();
        this.nickChangeButton.onClick.AddListener(() => {
            Instantiate(nicknameChangePopupPrefab);
            Debug.Log("팝업창 생성");
        });
    }

}

실행영상

UIStage

UIMain

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

public class Test03UIMain : MonoBehaviour
{
    [SerializeField]
    private Test03UIStage uiStage;

    [SerializeField]
    private Button[] arrBtns;
    // Start is called before the first frame update
    void Start()
    {
        this.uiStage.Init(1);
        for(int i=0; i < this.arrBtns.Length; i++)
        {
            Button btn = this.arrBtns[i];
            int index = i;
            btn.onClick.AddListener(() => {
                var state = (Test03UIStage.eState)index;
                Debug.LogFormat("{0}, {1}",index, state);
                this.uiStage.ChangeState(state);
            });
        }
    }
}

UIStage

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

public class Test03UIStage : 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 = eState.Lock;

    public void Init(int stageNum)
    {
        foreach(var tmpText in this.arrTxtStageNum)
        {
            tmpText.text = stageNum.ToString();
        }

        this.ChangeState(eState.Lock);
    }

    public void ChangeState(eState state)
    {
        this.InActiveAll();

        this.state = state;
        int index = (int)this.state;
        this.arrStateGo[index].SetActive(true);
    }
    private void InActiveAll()
    {
        foreach(var go in this.arrStateGo)
        {
            go.SetActive(false);
        }
    }
}

버튼 누르면 변화

UIStage

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

public class Test03UIStage : 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 = eState.Lock;


    private Button button;
    private int stageNum;

    public Button Button
    {
        get { return button; }
    }

    public void Init(int stageNum)
    {
        this.button = this.GetComponent<Button>();
        this.stageNum = stageNum;
        foreach(var tmpText in this.arrTxtStageNum)
        {
            tmpText.text = stageNum.ToString();
        }
        if (stageNum == 1) this.ChangeState(eState.Doing);
        else  this.ChangeState(eState.Lock);
    }

    public void ChangeState(eState state)
    {
        this.InActiveAll();

        this.state = state;
        int index = (int)this.state;
        this.arrStateGo[index].SetActive(true);
    }
    private void InActiveAll()
    {
        foreach(var go in this.arrStateGo)
        {
            go.SetActive(false);
        }
    }
}

UIStageController

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

public class Test03UIStageController : MonoBehaviour
{
    [SerializeField]
    private Test03UIStage[] arrUiStage;
    
    public void Init()
    {
       for(int i=0; i<arrUiStage.Length; i++)
        {
            int index = i;
            arrUiStage[i].Init(i + 1);
            arrUiStage[i].Button.onClick.AddListener(() => {
                //Lock 상태면 클릭 금지 
                if (arrUiStage[index].State != Test03UIStage.eState.Lock)
                {
                    arrUiStage[index].ChangeState(Test03UIStage.eState.Complete);
                    if (index + 1 < arrUiStage.Length) //에러 피하기 위함 
                        arrUiStage[index + 1].ChangeState(Test03UIStage.eState.Doing);
                }
            });
        }
    }
}

UIMain

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

public class Test03UIMain : MonoBehaviour
{
    [SerializeField]
    private Test03UIStageController uiStageController;

    [SerializeField]
    private Button[] arrBtns;
    // Start is called before the first frame update
    void Start()
    {
        this.uiStageController.Init();
    }
}

Lock 상태면 클릭되지 않는다.

정보 받아와서 상태 적용하기 

using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class UIStageController : MonoBehaviour
{
    [SerializeField]
    private Test03UIStage[] arrUiStage;

    public void Init()
    {
        string filePath = string.Format("{0}/stage_info.json", Application.persistentDataPath);
        string json = File.ReadAllText(filePath);
        StageInfo[] stageInfos = JsonConvert.DeserializeObject<StageInfo[]>(json);
        foreach( StageInfo stageInfo in stageInfos)
        {
            Debug.LogFormat("stageInfo.stageNum : {0}",stageInfo.stageNum);
            for(int i=0; i<arrUiStage.Length; i++)
            {
                arrUiStage[i].Init(i + 1);
                if (arrUiStage[i].StageNum == stageInfo.stageNum)
                {
                    arrUiStage[i].StarCount = stageInfo.starCount;
                    arrUiStage[i].State = (Test03UIStage.eState)stageInfo.state;
                }
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;

public class Test03UIStage : MonoBehaviour
{
    public enum eState
    {
        Lock,Doing,Complete
    }
    [SerializeField] private TMP_Text[] arrTxtStageNum;

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

    [SerializeField] private GameObject[] arrStarGo;

    private eState state = eState.Lock;

    public eState State
    {
        get { return state; }
        set { state = value; }
    }

    private Button button;
    private int stageNum;

    public int StageNum
    {
        get { return stageNum; }
    }

    public Button Button
    {
        get { return button; }
    }

    private int starCount;

    public int StarCount
    {
        get { return starCount; }
        set { starCount = value; }
    }
    public void Init(int stageNum)
    {
        this.button = this.GetComponent<Button>();
        this.stageNum = stageNum;
        foreach(var tmpText in this.arrTxtStageNum)
        {
            tmpText.text = stageNum.ToString();
        }
        this.ChangeState(state);
        this.OnStar(this.starCount);
    }

    public void ChangeState(eState state)
    {
        this.InActiveAll();

        this.state = state;
        int index = (int)this.state;
        this.arrStateGo[index].SetActive(true);
    }
    private void InActiveAll()
    {
        foreach(var go in this.arrStateGo)
        {
            go.SetActive(false);
        }
    }

    private void OnStar(int starCount)
    {
        foreach (var go in this.arrStarGo)
        {
            go.SetActive(false);
        }

        for (int i=0; i<starCount; i++)
        {
            this.arrStarGo[i].SetActive(true);
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StageInfo
{
    public int stageNum;
    public int state;
    public int starCount;
    //생성자
    public StageInfo(int stageNum, int state, int starCount)
    {
        this.stageNum = stageNum;
        this.state = state;
        this.starCount = starCount;
    }
}

사용한 json 파일 정보

'유니티 심화' 카테고리의 다른 글

유니티 GUI (스크롤 뷰 및 셀) 및 데이터 연동  (0) 2023.09.07
유니티 GUI 3 (Stage UI)  (0) 2023.09.06
유니티 GUI  (0) 2023.09.04
Hero SHooter 개발일지 2  (0) 2023.09.03
유니티 데이터 연동  (0) 2023.09.01