EasyCastleUNITY

유니티 GUI 본문

유니티 심화

유니티 GUI

EasyCastleT 2023. 9. 4. 16:07

Button Click

버튼 배열

UIMain

캡쳐와 클로져 응용

Main

UIToggle

영역 잡기 예시

UI는 먼저 영역을 잡는 것이 좋다 

옆에 사진은 그 예시이다. 

 

사용되는 OnOff Toggle
UI Toggle 인스펙터
On구조

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

public class Test01UIToggle : MonoBehaviour
{
    public enum eState
    {
        On,Off
    }

    private eState state; //기본값은 On, 0이기에 

    [SerializeField]
    private Button btn;

    [SerializeField]
    private GameObject[] arrOnOff; 
    // Start is called before the first frame update
    void Start()
    {
        var go =this.arrOnOff[(int)this.state];
        go.SetActive(true);
        this.btn.onClick.AddListener(() => {
            eState prevState = this.state;
            //Debug.LogFormat("토글 버튼 클릭 Prev :{0}",this.state);
            //이전 상태 게임오브젝트 비활성화
            this.arrOnOff[(int)this.state].SetActive(false);
            //현재 상태를 반전 
            if (this.state == eState.On)
            {
                this.state = eState.Off;
            }
            else
            {
                this.state =eState.On;
            }
            //현재 게임오브젝트 활성화
            Debug.LogFormat("토글 버튼 클릭 {0} -> {1}", prevState, this.state);
            var go = this.arrOnOff[(int)this.state];
            go.SetActive(true);
            
        });
    }
}

시연 영상

전체적인 프로젝트 구조


프로젝트 구조

UITap

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

public class Test01UITap : MonoBehaviour
{
    [SerializeField]
    private TMP_Text[] arrText;
    [SerializeField]
    private GameObject selectedGo;
    [SerializeField]
    private GameObject unSelectedGo;
    public Button btn;

    public void Init(string menuName)
    {
        Debug.Log(menuName);
        foreach (var tmpText in this.arrText)
        {
            tmpText.text = menuName;
        }
    }

    public void Select()
    {
        this.selectedGo.SetActive(true);
        this.unSelectedGo.SetActive(false);
    }

    public void UnSelect()
    {
        this.selectedGo.SetActive(false);
        this.unSelectedGo.SetActive(true);
    }
}

UITapsController

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

public class Test01UITapsController : MonoBehaviour
{
    public enum eMeneType
    {
        One,
        Two,
        Three
    }
    [SerializeField] Test01UITap[] taps;
    [SerializeField] private string[] arrMenuNames;

    private eMeneType selectedMenuType;

    public void Init()
    {
        for (int i = 0; i < this.taps.Length; i++)
        {
            int idx = i;
            var uiTab = this.taps[i];
            uiTab.Init(this.arrMenuNames[i]);
            uiTab.btn.onClick.AddListener(() => {
                Debug.Log(idx);
                this.SelectMenu((eMeneType)idx);
            });
        }

        this.SelectMenu(eMeneType.One);
    }

    private void SelectMenu(eMeneType menuType)
    {
        foreach (var tab in this.taps)
        {
            tab.UnSelect();
        }

        int idx = (int)menuType;
        var uiTab = this.taps[idx];
        uiTab.Select();

        this.selectedMenuType = menuType;
        Debug.Log(this.selectedMenuType);
    }
}

UIButtons

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

public class Test01UIButtons : MonoBehaviour
{
    public enum eButtonType
    {
        Blue, Green, Red, Purple, Yellow, Brown, BlueGray, Mint, Gray, Dark
    }

    public System.Action<eButtonType> onButtonClicked;
    //UI안에 모든 것을 관리 
    [SerializeField] private Button[] buttons;
  
    public void Init()
    {

        for (int i = 0; i < buttons.Length; i++)
        {
            Button btn = buttons[i];
            int index = i; //캡쳐
            btn.onClick.AddListener(() => {
                Debug.Log(btn.name);
                //클로져: 람다 안에서 상위 스코프 변수에 접근
                //Debug.Log(index);
                eButtonType type = (eButtonType)index;
                this.onButtonClicked(type);
            });
        }
    }
}

UICheckBox

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

public class Test01UICheckBox : MonoBehaviour
{
    public enum eState
    {
        On, Off
    }

    private eState state;

    private Button button;
    [SerializeField]
    private GameObject[] arrOnOff;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    public void Init()
    {
        this.button = GetComponent<Button>();
        this.arrOnOff[(int)state].SetActive(true);
        this.button.onClick.AddListener(() => {
            eState prevState = this.state;
            //이전 상태 게임오브젝트 비활성화
            this.arrOnOff[(int)this.state].SetActive(false);
            //현재 상태를 반전 
            if (this.state == eState.On)
            {
                this.state = eState.Off;
            }
            else
            {
                this.state = eState.On;
            }

            //현재 게임오브젝트 활성화
            Debug.LogFormat("체크 박스 클릭 {0} -> {1}", prevState, this.state);
            var go = this.arrOnOff[(int)this.state];
            go.SetActive(true);
        });
    }
}

UIToggle

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

public class Test01UIToggle : MonoBehaviour
{
    public enum eState
    {
        On,Off
    }

    private eState state; //기본값은 On, 0이기에 

    [SerializeField]
    private Button btn;

    [SerializeField]
    private GameObject[] arrOnOff; 
    // Start is called before the first frame update
    void Start()
    {
        
    }

    public void Init()
    {
        var go = this.arrOnOff[(int)this.state];
        go.SetActive(true);
        this.btn.onClick.AddListener(() => {
            eState prevState = this.state;
            //Debug.LogFormat("토글 버튼 클릭 Prev :{0}",this.state);
            //이전 상태 게임오브젝트 비활성화
            this.arrOnOff[(int)this.state].SetActive(false);
            //현재 상태를 반전 
            if (this.state == eState.On)
            {
                this.state = eState.Off;
            }
            else
            {
                this.state = eState.On;
            }
            //현재 게임오브젝트 활성화
            Debug.LogFormat("토글 버튼 클릭 {0} -> {1}", prevState, this.state);
            var go = this.arrOnOff[(int)this.state];
            go.SetActive(true);

        });
    }
}

UIMain

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

public class Test01UIMain : MonoBehaviour
{
    [SerializeField] Test01UIButtons buttons;
    [SerializeField] Test01UICheckBox checkBox;
    [SerializeField] Test01UIToggle toggle;
    [SerializeField] Test01UITapsController tapsController;
    
    // Start is called before the first frame update

    public void Init()
    {
        this.buttons.onButtonClicked = (btnType) => {
            Debug.Log(btnType);
        };
        buttons.Init();
        checkBox.Init();
        toggle.Init();
        tapsController.Init();
    }
}

Main

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

public class Test01Main : MonoBehaviour
{
    //씬 안에 모든 것을 관리(UI 포함)
    [SerializeField] private Test01UIMain uiMain;
    // Start is called before the first frame update
    void Start()
    {
        this.uiMain.Init();
    }
}

시연 영상

UISlider

Slider 인스펙터

UIMain 갱신

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

public class Test01UIMain : MonoBehaviour
{
    [SerializeField] Test01UIButtons buttons;
    [SerializeField] Test01UICheckBox checkBox;
    [SerializeField] Test01UIToggle toggle;
    [SerializeField] Test01UITapsController tapsController;
    [SerializeField] Test01UISlider slider;
    
    // Start is called before the first frame update

    public void Init()
    {
        this.buttons.onButtonClicked = (btnType) => {
            Debug.Log(btnType);
        };
        buttons.Init();
        this.slider.onValueChanged = (value) => {
            Debug.LogFormat("[Test01UIMain] onValueChanged: {0}", value);
        };
        this.slider.Init(8, 16);
        checkBox.Init();
        toggle.Init();
        tapsController.Init();
    }
}

UISlider

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

public class Test01UISlider : MonoBehaviour
{
    [SerializeField]
    private Slider slider;
    [SerializeField]
    private TMP_Text txtMin;
    [SerializeField]
    private TMP_Text txtMax;

    public System.Action<float> onValueChanged;
    // Start is called before the first frame update
    void Start()
    {
        this.txtMin.text = this.slider.minValue.ToString();
        this.txtMax.text = this.slider.maxValue.ToString();

        this.slider.onValueChanged.AddListener((val) => {
            Debug.Log(val);
        });
    }

    public void Init(float min, float max)
    {
        this.slider.minValue = min;
        this.slider.maxValue = max;
        this.txtMin.text = this.slider.minValue.ToString();
        this.txtMax.text = this.slider.maxValue.ToString();

        this.slider.onValueChanged.AddListener((val) => {
            this.onValueChanged(val);
        });
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

슬라이더 시행 영상

중요한 점

계속 상위로 데이터를 전달할 필요가 있다. 

UI에 관한 것은 모두 UIMain으로 전달하고

이 전달받은 UIMain을 Main에 전달하는 방식으로 작동하도록 만든다. 

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

유니티 GUI 3 (Stage UI)  (0) 2023.09.06
유니티 GUI 2  (0) 2023.09.05
Hero SHooter 개발일지 2  (0) 2023.09.03
유니티 데이터 연동  (0) 2023.09.01
Hero Shooter 새로운 Input System 활용한 조이스틱 이동  (0) 2023.09.01