【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);
    }
}
相关推荐
JJJJ_iii2 小时前
【机器学习01】监督学习、无监督学习、线性回归、代价函数
人工智能·笔记·python·学习·机器学习·jupyter·线性回归
知识分享小能手4 小时前
uni-app 入门学习教程,从入门到精通,uni-app基础扩展 —— 详细知识点与案例(3)
vue.js·学习·ui·微信小程序·小程序·uni-app·编程
今夕资源网5 小时前
牛童三国单机游戏Unity源码 免费开源
游戏·unity·单机游戏·游戏源码·unity源码·unity游戏
Larry_Yanan8 小时前
QML学习笔记(四十二)QML的MessageDialog
c++·笔记·qt·学习·ui
能不能别报错8 小时前
K8s学习笔记(十九) K8s资源限制
笔记·学习·kubernetes
Javashop_jjj9 小时前
三勾软件| 用SpringBoot+Element-UI+UniApp+Redis+MySQL打造的点餐连锁系统
spring boot·ui·uni-app
sulikey9 小时前
【Linux权限机制深入理解】为何没有目录写权限仍能修改文件权限?
linux·运维·笔记·ubuntu·centos
十安_数学好题速析9 小时前
倍数关系:最多能选出多少个数
笔记·学习·高考
Hello_Embed10 小时前
STM32 环境监测项目笔记(一):DHT11 温湿度传感器原理与驱动实现
c语言·笔记·stm32·单片机·嵌入式软件
程序员大雄学编程11 小时前
「深度学习笔记4」深度学习优化算法完全指南:从梯度下降到Adam的实战详解
笔记·深度学习·算法·机器学习