여러개의 UI를 다룰 때 어떤 UI를 제일 먼저 표시할지 관리를 해주어야 한다. 사용자가 누른 UI를 제일 위로 올리는것과 특정 키를 누르면 닫히는 것과 같은 관리를 해주어야 한다.
UI의 우선순위를 다루는 것은
Sort order
이다.
UI는 크게 두 가지로 나눌 수 있다.
UI의 종류마다 관리할 방법과 구현해야 할 요소들이 다르기 때문에 코드를 나누어 작성해야 한다. 예를 들면 아래와 같은 구조로 UI를 배치할 수 있다.
* UI_Base
ㄴ UI_Popup
ㄴ UI_Inventory
ㄴ UI_Option
ㄴ UI_Scene
ㄴ UI_Map
Popup UI는 입력에 따라 UI를 키고 끌 수 있어야 한다.
Sort Order
를 지정해주어야 한다.popup UI 같은 경우 이후에 가장 최근에 킨 UI부터 끄기를 원하기 때문에 stack
을 사용한다. 물론 다른 자료구조를 사용해도 되지만 stack
을 사용한다면 이후에 기능을 구현할 때 더 쉽게 구현이 가능할 것이다.
Stack<UI_Popup> _popupStack = new Stack<UI_Popup>();
GameObject
를 저장하는 것이 아닌 UI_Popup
을 상속받은 모든 UI클래스를 저장한다.
UI를 생성하는 단계는 다음과 같이 구성된다.
생성한 GameObject의 Parent를 설정하는 이유는 여러개의 UI를 생성할 때 여러 UI를 하나의 GameObject의 산하로 두어 관리하기 쉽게하기 위함이다.
public T ShowPopupUI<T>(string name = null) where T : UI_Popup
{
if (string.IsNullOrEmpty(name))
name = typeof(T).Name;
GameObject go = Managers.Resource.Instantiate($"UI/Popup/{name}");
T popup = Util.GetOrAddComponent<T>(go);
_popupStack.Push(popup);
go.transform.SetParent(Root.transform);
return popup;
}
UI를 끄는 것은 stack의 top에 있는 UI를 순차적으로 지우면 된다.
public void ClosePopupUI()
{
if (_popupStack.Count == 0)
return;
UI_Popup popup = _popupStack.Pop();
Managers.Resource.Destroy(popup.gameObject);
popup = null;
_order--;
}
SortOrder의 설정은 Canvas Component에 있다. 어떤 GameObject에 대해 popup UI
인지 scene UI
인지 구분을 한 뒤 Sort Order를 설정해주어야 한다.
public void SetCanvas(GameObject go, bool sort = true)
{
Canvas canvas = Util.GetOrAddComponent<Canvas>(go);
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvas.overrideSorting = true;
if (sort)
{
canvas.sortingOrder = (_order);
_order++;
}
else
{
canvas.sortingOrder = 0;
}
}
2개 이상의 UI가 켜져있을 때 최상위의 UI를 제외하고 다른 UI를 조작할 수 없도록 하고 싶을 때 Blocker를 설정할 수 있다.
Raycast Target
옵션을 킨다.위와 같이 설정하면 다른 UI의 조작을 할수 없게 만드는 Blocker를 만들 수 있다.
Component의 위치를 최상단으로 하지 않으면 동작시키고자 하는 UI의 입력을 막아버린다.