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,
}
UIManager

  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;
    }
}
UIBase
原文地址:https://www.cnblogs.com/Joke-crazy/p/10478397.html