유니티 심화
유니티 GUI
EasyCastleT
2023. 9. 4. 16:07
Button Click
UIMain
Main
UIToggle
UI는 먼저 영역을 잡는 것이 좋다
옆에 사진은 그 예시이다.
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
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에 전달하는 방식으로 작동하도록 만든다.