using System.Collections.Generic; using UnityEngine; public class UIManager { // UIManager 를 왜 만들어? == Canvas의 Sort Order 관리하기 위해서 만든다. // PopUP을 위해서 관리를 하는거고 PopUP은 Stack 구조로 관리하는게 좋다. // 그리고 소팅 안하는 씬같은 경우 오더의 수가 0으로 고정을 해놨기에 오더의 초기값을 0이 아닌 다른값으로 하는게 좋다. // 10으로 하는건 혹시나 0~9를 앞에서 사용하게 하거나 먼저 띄우고 싶은게 있을 수 있으니 비워둔다. int _order = 10; Stack _popupStack = new Stack(); UI_Scene _sceneUI = null; // 그냥 Popup을 계속 띄우게 되면 이게 플레이 씬 볼때 굉장히 복잡하게 나타나는대 이걸 빈 게임 오브젝트를 만들어서 관리하게 한다. // 약간 폴더 같은 느낌이라 보면 된다. public GameObject Root { get { GameObject root = GameObject.Find("@UI_Root"); if (root == null) { root = new GameObject { name = "@UI_Root" }; } return root; } } // 이게 위치하는 곳은 UI_Scene와 UI_Popup의 시작부분에 위치해야 한다. public void SetCanvas(GameObject go, bool sort = true) { Canvas canvas = Util.GetOrAddComponent(go); canvas.renderMode = RenderMode.ScreenSpaceOverlay; // 캔버스 안에 캔버스가 있을때 그게 어떤 값을 가지고 있어도 내껀 내꺼다 라는 옵션이다. canvas.overrideSorting = true; if (sort) canvas.sortingOrder = _order++; else canvas.sortingOrder = 0; // UI가 이벤트를 받으려면 반드시 필요 Util.GetOrAddComponent(go); } // name = 프리팹의 의 이름 // 인자로 받는 T = 스크립트의 이름 public T ShowPopupUI(string name = null) where T : UI_Popup { if (string.IsNullOrEmpty(name)) name = typeof(T).Name; // Resources/Prefabs/UI/Popup/폴더에서 name과 일치하는 프리팹을 로드한다. GameObject go = Managers.Resource.Instantiate($"UI/Popup/{name}"); T popup = Util.GetOrAddComponent(go); _popupStack.Push(popup); // 그냥 order++ 하면 1,2,3,4,5 ... 이렇게 올라가는데 중요한건 이 방법을 통하지 않고 // 그냥 유니티에서 바로 씬에 오브젝트를 올려 버리면 이 오더값이 꼬일 수 있다. // 그래서 여기에서 바로 넣는게 아니라 UI_Popup에서 바로 초기화해서 확인하게 하는게 좋다. go.transform.SetParent(Root.transform); return popup; } public void ClosePopupUI() { if (_popupStack.Count == 0) return; UI_Popup popup = _popupStack.Pop(); Managers.Resource.Destroy(popup.gameObject); // 삭제 했는데 접근하면 안되니까 이제 이 값을 날려서 접근자체를 막아 버리기 popup = null; _order--; } // 스택이라 마지막이 날아가야 하는데 혹시나 아닐 경우 체크하는 버전 public void ClosePopupUI(UI_Popup popup) { if (_popupStack.Count == 0) return; if (_popupStack.Peek() != popup) { Debug.Log("Close Popup Failed!"); return; } ClosePopupUI(); } public void CloseAllPopupUI() { while (_popupStack.Count > 0) ClosePopupUI(); } public T ShowSceneUI(string name = null) where T : UI_Scene { if (string.IsNullOrEmpty(name)) name = typeof(T).Name; GameObject go = Managers.Resource.Instantiate($"UI/Scene/{name}"); T scene = Util.GetOrAddComponent(go); _sceneUI = scene; go.transform.SetParent(Root.transform); return scene; } public T MakeSubItem(Transform parent, string name = null) where T : UI_Base { if (string.IsNullOrEmpty(name)) name = typeof(T).Name; GameObject go = Managers.Resource.Instantiate($"UI/SubItem/{name}"); if (parent != null) { go.transform.SetParent(parent); } return Util.GetOrAddComponent(go); } public void Clear() { CloseAllPopupUI(); _sceneUI = null; } }