【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);
    }
}
相关推荐
乐橙开放平台14 分钟前
养老 SaaS 笔记:setMessageCallback 事件桥接 + msgType 映射 P0/P1,先 ACK 再分流值班流
笔记·物联网·音视频·智能家居
晓梦林1 小时前
Tools2靶场学习笔记
笔记·学习
i love you china3 小时前
问卷系统调查博客项目测试报告
笔记
疯狂打码的少年4 小时前
【数据结构】板块总结 + 下期预告(数据库技术)
数据结构·笔记·算法
zQ.ii4 小时前
WPF 触发器学习笔记
笔记·学习·wpf
小贺儿开发4 小时前
Unity 局域网遥控幻灯片展示工具 1.0
unity·网络通信·工具·ppt·控制·网页·互动
乐橙开放平台4 小时前
老旧社区双通道笔记:周界 hoveringAlarm / aiPerArea + 电梯 aiNonVehDetect,一套 callback 做 24h 防护
笔记·物联网·音视频·智能家居
想要成为老金高手4 小时前
Kubernetes 实战笔记(一):Pod 管理与 kubectl 核心命令全解
笔记·容器·kubernetes
程序员麻辣烫4 小时前
反曲弓射箭笔记
笔记·生活
xy34535 小时前
Axure 9.0 条形图绘制超详细教程:静态展示
ui·产品经理·axure·条形图