首页 学习日记正文

Unity界面管理器封装

阿沐 学习日记 2020-04-16 765 0 unity

Unity界面管理器封装

image.png

1、使用场景:

UI面板显示/隐藏,适用于同一个场景内跳转面板

2、实现思路:

将显示UI所需要的画布Canvas和EventSystem设置为跨场景不销毁对象,将其他ui面板全部设置为预制体,用户即可自定义动态加载面板显示或者隐藏

3、具体实现:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// 层级 枚举
/// </summary>
public enum UILevel
{
    Bot,
    Mid,
    Top,
    System
}

/// <summary>
/// UI界面管理器:处理面板显示/隐藏
/// </summary>
public class UIManager : SingletonBase<UIManager>
{
    private Transform bot;//最低层级
    private Transform mid;//中间层级
    private Transform top;//最上层级
    private Transform system;//系统层级
    //字典 用来保存、管理 面板
    private Dictionary<string, UIBasePanel> panelDict = new Dictionary<string, UIBasePanel>();
    public UIManager()
    {
        GameObject canvasObj = ResController.GetInstance().LoadAsset<GameObject>("UIPanel/Canvas");//找到画布
        GameObject eventSystem = ResController.GetInstance().LoadAsset<GameObject>("UIPanel/EventSystem");//找到系统的ui事件检测
        //设置过场景不销毁
        GameObject.DontDestroyOnLoad(canvasObj);
        GameObject.DontDestroyOnLoad(eventSystem);
        //找到四个层级
        bot = canvasObj.transform.Find("bot");
        mid = canvasObj.transform.Find("mid");
        top = canvasObj.transform.Find("top");
        system = canvasObj.transform.Find("system");
    }

    /// <summary>
    /// 加载面板 显示
    /// </summary>
    /// <typeparam name="T">面板挂载的脚本类型</typeparam>
    /// <param name="panelPath">面板路径</param>
    /// <param name="level">面板需要显示在的层级</param>
    /// <param name="callBack">面板挂载脚本要执行的逻辑</param>
    public void ShowUIPanel<T>(string panelPath,UILevel level=UILevel.Bot,UnityAction<T> callBack=null) where T:UIBasePanel
    {
        //第二次加载同一个面板时
        string s = panelPath.Split('/')[panelPath.Split('/').Length - 1];
        if (panelDict.ContainsKey(s))
        {
            if (callBack != null)
                callBack(panelDict[s] as T);
            return;
        }

        //异步加载面板预制体
        ResController.GetInstance().LoadAssetAsync<GameObject>(panelPath, (obj) => {
            //指定层级
            Transform father = null;
            switch (level)
            { 
                case UILevel.Mid:
                    father = mid;
                    break;
                case UILevel.Top:
                    father = top;
                    break;
                case UILevel.System:
                    father = system;
                    break;
                default:
                    father = bot;
                    break;
            }
            //设置层级
            obj.transform.SetParent(father);
            //设置面板位置
            obj.transform.localPosition = Vector3.zero;
            obj.transform.localScale = Vector3.one;
            (obj.transform as RectTransform).offsetMax = Vector2.zero;
            (obj.transform as RectTransform).offsetMin = Vector2.zero;

            //获取面板 继承了UIBasePanel 的脚本
            T panel=obj.GetComponent<T>();
            //执行回调函数
            if (callBack != null)
            {
                callBack(panel);
            }
            //将创建的面板加入到字典
            panelDict.Add(s, panel);
        });
    }

    /// <summary>
    /// 隐藏面板
    /// </summary>
    /// <param name="name">面板名称</param>
    public void HideUIPanel(string name)
    {
        if (panelDict.ContainsKey(name))
        {
            //销毁面板 字典移除
            GameObject.Destroy(panelDict[name].gameObject);
            panelDict.Remove(name);
        }
    }
}

测试:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIShow : MonoBehaviour {

    void Start ()
    {
        UIManager.GetInstance().ShowUIPanel<UITest>("UIPanel/LoginPanel", UILevel.Top, LoginSuccess);//加载显示面板
    }

    private void LoginSuccess(UITest test)
    {
        Debug.Log("登入界面加载完成");

        Invoke("DestoryPanel",4);
    }

    private void DestoryPanel()
    {
        UIManager.GetInstance().HideUIPanel("LoginPanel");//隐藏面板
    }

	
}

效果:

image.png

打赏

评论

Music