【Unity笔记01】基于单例模式的简单UI框架

单例模式的UIManager

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIManager 
{
    private static UIManager _instance;
    public Dictionary<string, string> pathDict;
    public Dictionary<string, GameObject> prefabDict;
    public Dictionary<string, BasePanel> panelDict;
    private Transform _uiRoot;
    //单例模式
    public static UIManager Instance
    {
        get
        {
            if( _instance == null )
            {
                _instance = new UIManager();

            }
            return _instance;
        }
    }
    private UIManager()
    {
        Init();
    }
    private void Init()
    {
        prefabDict = new Dictionary<string, GameObject>();
        panelDict = new Dictionary<string, BasePanel>();
        pathDict = new Dictionary<string, string>()
        {
            {UIConst.Menu,"Prefabs/Pop/Menu" },
            {UIConst.SettingPop,"Prefabs/Pop/SettingPop" },
            {UIConst.OtherPop,"Prefabs/Pop/OtherPop" }
        };

    }
    public Transform UIRoot
    {
        get
        {
            if( _uiRoot == null )
            {
                _uiRoot = GameObject.Find("Canvas").transform;
            }
            return _uiRoot;
        }
    }

    public BasePanel OpenPanel(string name, bool isOnly = true)
    {
        //如果要只显示一个弹窗的话
        if(isOnly)
        {
            CloseAllPops(name);
        }
        BasePanel panel = null;
        if(panelDict.TryGetValue(name, out panel))
        {
            Debug.Log("界面已经打开过" + name);
            panel.OpenPanel(name);
            return null;
        }
        string path = "";
        if( !pathDict.TryGetValue(name, out path) )
        {
            Debug.Log("路径错误"+path);
            return null;
        }
        GameObject panelPrefab = null;
        if(!panelDict.TryGetValue(name, out panel))
        {
            string realPath =path;
            panelPrefab=Resources.Load<GameObject>(realPath);
            prefabDict.Add(name, panelPrefab);
            
        }
        //open
        GameObject panelObject = GameObject.Instantiate(panelPrefab, UIRoot, false);
        Debug.Log(panelObject.name);
        panel= panelObject.GetComponent<BasePanel>();
        if( panel == null )
        {
            Debug.Log("没有脚本哦");
        }
        
        panelDict.Add(name,panel);
        panel.OpenPanel(name);
        return panel;

    }
    public bool ClosePanel(string name)
    {
        BasePanel panel= null;
        if(! panelDict.TryGetValue(name,out panel))
        {
            Debug.Log("界面未打开");
            return false;
        }
        panel.ClosePanel();
        return true;
    }
    public void CloseAllPops(string name)
    {
        foreach(var pair in panelDict)
        {
            if (pair.Key == name) continue;
            pair.Value.ClosePanel();
        }
    }
}

面板的基类

控制面板的打开和关闭,带动画

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class BasePanel : MonoBehaviour
{
    private bool isRemove = false;
    private string name;
    public virtual void OpenPanel(string name)
    {
        this.name = name;
        gameObject.SetActive(true);
        OpenAnimation(gameObject);
    }
    public virtual void ClosePanel()
    {
        isRemove = true;
        CloseAnimation(gameObject).OnComplete(() =>
        {
            gameObject.SetActive(false);

        });
        //gameObject.SetActive(false);
    }

    public void OpenAnimation(GameObject gameObject)
    {
        //用dotween 从0%放大到105% 再缩小到95% 再到100%
        //初始缩放为 0
        gameObject.transform.localScale = Vector3.zero;

        //创建动画序列
        Sequence scaleSequence = DOTween.Sequence();

        // 添加动画步骤
        scaleSequence.Append(gameObject.transform.DOScale(1.05f, 0.3f)); // 放大到 105%
        scaleSequence.Append(gameObject.transform.DOScale(0.95f, 0.3f)); // 缩小到 95%
        scaleSequence.Append(gameObject.transform.DOScale(1.0f, 0.3f));  // 回到 100%

        // 缓动
        scaleSequence.SetEase(Ease.OutBack);
    }
    public Tween CloseAnimation(GameObject gameObject)
    {
        Sequence scaleSequence = DOTween.Sequence();
        scaleSequence.Append(gameObject.transform.DOScale(0f, 0.2f));
        
        return scaleSequence;
    }
}

常量

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIConst 
{
    public const string Menu = "Menu";
    public const string SettingPop = "SettingPop";
    public const string OtherPop = "OtherPop";
}

使用

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MenuPanel : BasePanel
{
    public void OpenNest()
    {
        UIManager.Instance.OpenPanel(UIConst.OtherPop);
    }
    public void Close()
    {
        UIManager.Instance.ClosePanel(UIConst.Menu);
    }
}
相关推荐
你我约定有三4 小时前
前端笔记:同源策略、跨域问题
前端·笔记
龚子亦5 小时前
【Unity开发】数据存储——XML
xml·unity·游戏引擎·数据存储·游戏开发
XXYBMOOO5 小时前
使用全局变量访问 Qt UI 组件的方法文档
c++·qt·ui
智者知已应修善业6 小时前
【C# 找最大值、最小值和平均值及大于个数和值】2022-9-23
经验分享·笔记·算法·c#
秋也凉7 小时前
关于JavaWeb的总结笔记
笔记
YGY Webgis糕手之路7 小时前
OpenLayers 快速入门(六)Interaction 对象
前端·vue.js·经验分享·笔记·web
Bryce李小白8 小时前
Flutter 主流 UI 框架总结归纳
flutter·ui
write_the_code8 小时前
Unity国际版下载链接分享(非c1国内版)
unity·游戏引擎
徒 花9 小时前
初级网安作业笔记3
笔记
Bulling_9 小时前
unity动态背景制作
unity·游戏引擎