[Unity] Unity UI 관리법
카테고리: Unity
Unity의 UI 관리법
유니티의 UI 관리법은 Canvas를 위에 두고, 그 위에 컴포넌트들을 그리는 방식으로 작동합니다. 이를 UGUI 라고 합니다.
UI를 관리하는 방법은 셀 수 없이 많지만, 저는 이번에 UI마다 컴포넌트를 만들어서 관리하는 방법을 사용하였습니다.
또한, 상속을 이용하여 각 UI들의 성질을 미리 정의 한 후, 캡슐화 하여 모든 버튼들이 캡슐화된 함수를 참조하도록 만들었습니다.
예시는 UI_YesNoDialog 를 가져왔습니다.
UI 컴포넌트 만들기
우선 제가 만든 하이어라키 구조 입니다. 자식으로 달려있는 Button 이나 Text를 찾기 위한 방법으로는 public
필드로 만들어서 드래그 앤 드롭 하기, 또는 GetComponentInChildren
을 사용하여 참조를 가져옵니다.
public
필드로 모든 객체들을 드래그 앤 드롭 할 시, 객체지향에서 많이 벗어나기 때문에, 저는 GetComponentInChildren
으로 전부 찾아주었습니다. 하지만 GetComponentInChildren을 하기 위해서는 Generic 안에 찾아야 할 객체의 타입을 넣어주어야 합니다. 그렇기 때문에 제어가 필요한 UI에 클래스를 만들어 다 붙여주었습니다.
public class UI_YesNoDialog : UI_Popup
{
#region UI
private UI_YesNoDialog_Button_Yes buttonYes = null;
private UI_YesNoDialog_Button_No buttonNo = null;
private UI_YesNoDialog_Text_Content contentText = null;
private UI_YesNoDialog_Text_Title titleText = null;
private UI_YesNoDialog_Image_Background imageBackground = null;
#endregion
private Action onYesButtonClickCallback = null;
private Action onNoButtonClickCallback = null;
protected override void Awake()
{
base.Awake();
buttonYes = GetComponentInChildren<UI_YesNoDialog_Button_Yes>();
buttonNo = GetComponentInChildren<UI_YesNoDialog_Button_No>();
contentText = GetComponentInChildren<UI_YesNoDialog_Text_Content>();
titleText = GetComponentInChildren<UI_YesNoDialog_Text_Title>();
imageBackground = GetComponentInChildren<UI_YesNoDialog_Image_Background>();
}
}
이렇게만 하면, Button 이든 Text 이든 다시 GetComponent를 해야하기 때문에, 그 과정을 줄이고자 상속을 사용하여 중복코드를 제거하였습니다.
상속구조는 UI_Base
- UI_SubItem
- UI_Button
입니다.
🗅 class UI_YesNoDialog_Button_Yes
public class UI_YesNoDialog_Button_Yes : UI_Button
{
}
🗅 class UI_Button
public class UI_Button : UI_SubItem
{
protected Button button = null;
private UnityAction onClickEvent = null;
protected override void Awake()
{
base.Awake();
button = GetComponent<Button>();
}
public void SetOnClickEvent(UnityAction _onClickEvent)
{
button.onClick.RemoveAllListeners();
button.onClick.AddListener(PlayButtonClickSound);
button.onClick.AddListener(_onClickEvent);
}
}
이런식으로 구현 한 후, Button
에 OnClick
이벤트를 달고 싶다면 제어하는 UI 스크립트에서 다음과 같이 사용하면 됩니다.
🗅 class UI_YesNoDialog
public class UI_YesNoDialog : UI_Popup
{
public void Init(string _titleString, string _contentString, Action _onYesButtonClick, Action _onNoButtonClick)
{
SetText(_titleString, _contentString);
SetOnYesButtonClickCallback(_onYesButtonClick);
SetOnNoButtonClickCallback(_onNoButtonClick);
SetChildButtonClickEvent();
}
public void SetChildButtonClickEvent()
{
buttonYes.SetOnClickEvent(OnYesButtonClick);
buttonNo.SetOnClickEvent(OnNoButtonClick);
}
}
이런식으로 OnClick
이벤트를 달아줄 수 있습니다. 그 외에도 버튼의 색상을 바꾼다던지, 버튼에 사운드를 입힌다던지의 기능들을 UI_Button
에서 한번에 관리할 수 있기 때문에, 수정에 용이하다는 장점이 있습니다.
UI_Button
을 상속받기만 하고, SetOnClickEvent 만 해준다면 한번의 수정으로 모든 버튼들을 수정할 수 있습니다.
또한, 결합도를 낮추기 위해 위의 스크립트에서 볼 수 있듯이, 모든 버튼이벤트들을 Callback
으로 분리해 Init
에서 넣어주도록 하였습니다.
실제 사용
실제로 Dialog를 띄우는 코드입니다. Close()
와 Show()
도 UI_Base
의 확장 메서드 이므로, 애니메이션을 추가하던지, 다른 작업을 추가하던지 도 확장 가능합니다.
private void Test_UI_YesNoDialog()
{
UI_YesNoDialog dialog = UIManager.Instance.GetOrInstantiateWithPool<UI_YesNoDialog>();
dialog.Init("YesNoDialog", "YesNoDialog Content", () => { dialog.Close(); }, () => { dialog.Close(); });
dialog.Show();
}
댓글 남기기