【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);
    }
}
相关推荐
2301_764441332 小时前
Aella Science Dataset Explorer 部署教程笔记
笔记·python·全文检索
派大鑫wink3 小时前
【Java 学习日记】开篇:以日记为舟,渡 Java 进阶之海
java·笔记·程序人生·学习方法
永远都不秃头的程序员(互关)3 小时前
大模型Agent落地实战:从核心原理到工业级任务规划器开发
笔记
TL滕5 小时前
从0开始学算法——第十八天(分治算法)
笔记·学习·算法
算法与双吉汉堡5 小时前
【短链接项目笔记】Day2 用户注册
java·redis·笔记·后端·spring
思成不止于此5 小时前
【MySQL 零基础入门】MySQL 约束精讲(一):基础约束篇
数据库·笔记·sql·学习·mysql
小新1107 小时前
vs2022+Qt插件初体验,创建带 UI 界面的 Qt 项目
开发语言·qt·ui
WizLC7 小时前
【JAVA】JVM类加载器知识笔记
java·jvm·笔记
TL滕7 小时前
从0开始学算法——第十八天(分治算法练习)
笔记·学习·算法
لا معنى له8 小时前
学习笔记:卷积神经网络(CNN)
人工智能·笔记·深度学习·神经网络·学习·cnn