UIManager
创建UIManager,管理所有UI面板
准备工作:
1. 创建Canvas并设置Tag为Main Canvas
2. 在Canvas下新建五个层级节点,因为UGUI显示层级越往下越靠前
using System; using System.Collections.Generic; using UnityEngine; public class UIManager : Singleton<UIManager> { public UIManager() { Init(); } private List<Transform> m_parent = new List<Transform>(); private List<UIBase> m_panel = new List<UIBase>(); private int current_ID; private void Init() { GameObject canvas = GameObject.FindGameObjectWithTag("Main Canvas"); if (canvas != null) { UnityEngine.UI.CanvasScaler scale = canvas.GetComponent<UnityEngine.UI.CanvasScaler>(); if (Screen.width / (float)Screen.height > 16 / 9f) { scale.matchWidthOrHeight = 1; } //获取节点 for (int i = 0; i < (int)PanelType.Count; i++) { PanelType _panel = (PanelType)i; m_parent.Add(canvas.transform.Find(_panel.ToString())); } } else { Debug.LogError("Can't Find a GameObject whose Tag is 'Main Canvas'!"); } } public void Open<T>(string panel_name, bool onlyOne = true, PanelType panel_type = PanelType.Window, PanelEvent panel_event = PanelEvent.None) where T : UIBase, new() { Transform parent = GetParent(panel_type); switch (panel_event) { case PanelEvent.Hide_Pre: if (m_panel.Count != 0) { m_panel[m_panel.Count - 1].SetActive(false); } break; case PanelEvent.Close_Pre: if (m_panel.Count != 0) { m_panel[m_panel.Count - 1].Close(); m_panel.RemoveAt(m_panel.Count - 1); } break; case PanelEvent.Close_All: for (int i = 0; i < m_panel.Count; i++) { m_panel[i].Close(); } m_panel.Clear(); break; default: break; } try { UIBase panel = null; if (onlyOne) { for (int i = 0; i < m_panel.Count; i++) { if (m_panel[i].panel_name == panel_name) { panel = m_panel[i]; m_panel.RemoveAt(i); break; } } if (panel != null) { panel.SetParent(parent); panel.First(); panel.Reopen(); } else { panel = InitPanel<T>(panel_name, parent); } } else { panel = InitPanel<T>(panel_name, parent); } panel.panel_ID = NextID(); panel.panel_name = panel_name; panel.panel_type = panel_type; m_panel.Add(panel); } catch (Exception e) { Debug.LogError(e.Message); } } public void Back() { if (m_panel.Count != 0) { m_panel[m_panel.Count - 1].Close(); m_panel.RemoveAt(m_panel.Count - 1); } //刷新当前界面 if (m_panel.Count != 0) { m_panel[m_panel.Count - 1].Reopen(); } } public void Close(int panel_ID) { for (int i = 0; i < m_panel.Count; i++) { if (m_panel[i].panel_ID == panel_ID) { m_panel[i].Close(); m_panel.RemoveAt(i); break; } } } public void Close(string panel_name) { for (int i = 0; i < m_panel.Count; i++) { if (m_panel[i].panel_name == panel_name) { m_panel[i].Close(); m_panel.RemoveAt(i); break; } } } public void Close_All() { for (int i = 0; i < m_panel.Count; i++) { m_panel[i].Close(); } m_panel.Clear(); } public void Main() { for (int i = 0; i < m_panel.Count; i++) { m_panel[i].Close(); } m_panel.Clear(); Open<UI_Test>("UI_Main"); } public UIBase Top() { if (m_panel.Count > 0) { return m_panel[m_panel.Count - 1]; } else { return null; } } public UIBase Get(int panel_ID) { return m_panel.Find(x => x.panel_ID == panel_ID); } public UIBase Get(string panel_name) { return m_panel.Find(x => x.panel_name == panel_name); } private UIBase InitPanel<T>(string panel_name, Transform parent) where T : UIBase { UIBase component = null; //从对象池获取 GameObject go = PoolManager.Instance.Pop(panel_name); if (go == null) { //PanelData.Path[?]自定义数据存储预制体路径 string panel_path = PanelData.Path[panel_name]; GameObject prefab = Resources.Load<GameObject>(panel_path); go = GameObject.Instantiate(prefab, parent); } else { go.transform.SetParent(parent, true); } component = go.GetComponent<T>(); if (component == null) { component = go.AddComponent<T>(); } return component; } private Transform GetParent(PanelType panel_type) { Transform parent = null; try { parent = m_parent[(int)panel_type]; } catch (Exception e) { Debug.LogError(e.Message); } return parent; } private int NextID() { if (++current_ID >= int.MaxValue) { current_ID = 0; } return current_ID; } } public enum PanelType { Bottom, Base, Window, Widget, Top, Count, } public enum PanelEvent { None, Hide_Pre, Close_Pre, Close_All, }
UIBase是抽象类,需创建实例类继承
using System; using System.Collections; using UnityEngine; public abstract class UIBase : MonoBehaviour { [HideInInspector] public int panel_ID; [HideInInspector] public string panel_name; [HideInInspector] public PanelType panel_type; protected CanvasGroup panel_canvas; public virtual void Close(Action callBack = null) { if (callBack != null) { callBack(); } PoolManager.Instance.Push(panel_name, gameObject); } public virtual void Reopen() { Refresh(); SetActive(true); } public virtual void Refresh() { } public void Delay(float time, Action callBack = null) { StartCoroutine(DelayedExecution(time, callBack)); } private IEnumerator DelayedExecution(float time, Action callBack) { yield return new WaitForSeconds(time); if (callBack != null) { callBack(); } } public void First() { if (transform.parent != null) { transform.SetSiblingIndex(transform.parent.childCount - 1); } } public void SetName(string name) { transform.name = name; } public void SetActive(bool active) { if (gameObject.activeSelf != active) { gameObject.SetActive(active); } } public void SetActive_Canvas(bool active) { if (panel_canvas != null) { panel_canvas.alpha = active ? 1 : 0; panel_canvas.interactable = active; panel_canvas.blocksRaycasts = active; } } public void SetParent(Transform parent) { if (transform.parent != parent) { transform.SetParent(parent); } } public override string ToString() { return panel_name; } }