Unity_Learn/Assets/Scripts/Managers/UIManager.cs
2025-09-05 16:04:55 +09:00

115 lines
4.0 KiB
C#

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<UI_Popup> _popupStack = new Stack<UI_Popup>();
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<Canvas>(go);
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
// 캔버스 안에 캔버스가 있을때 그게 어떤 값을 가지고 있어도 내껀 내꺼다 라는 옵션이다.
canvas.overrideSorting = true;
if (sort)
canvas.sortingOrder = _order++;
else
canvas.sortingOrder = 0;
// UI가 이벤트를 받으려면 반드시 필요
Util.GetOrAddComponent<UnityEngine.UI.GraphicRaycaster>(go);
}
// name = 프리팹의 의 이름
// 인자로 받는 T = 스크립트의 이름
public T ShowPopupUI<T>(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<T>(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<T>(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<T>(go);
_sceneUI = scene;
go.transform.SetParent(Root.transform);
return scene;
}
}