UI框架——核心类 UIManager.cs

在这里插入图片描述

/*
 *实现“缓存”“自动加载”“层级管理”的设计功能
 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace SUIFW
{
    public class UIManager : MonoBehaviour
    {
        #region 定义变量
        //三个重要字典
        //路径、所有窗体、当前显示窗体
        private Dictionary<string, string> _DicUIFormPaths;          //路径字典(通过窗体名获取路径)
        private Dictionary<string, BaseUIForm> _DicAllUIForms;       //所有窗体字典(缓存所有UI窗体)
        private Dictionary<string, BaseUIForm> _DicCurrentShowUIForms;//当前显示窗体 字典 集合
        private Stack<BaseUIForm> _StaCurrentShowUIForms;            //当前显示窗体 栈   集合
        
        //得到挂载节点
        private Transform traCanvas;
        private Transform traNormal;
        private Transform traFixed;
        private Transform traPopup;
        private Transform traUIScript;
        #endregion

        #region 设为单例类
        private static UIManager _Instance;
        public  static UIManager GetInstance()
        {
            if(_Instance==null)
            {
                _Instance = new GameObject("_UIManager").AddComponent<UIManager>();
            }
            return _Instance;
        }
        #endregion

        void Awake()//最重要的任务是,把Canvas预设体,挂到层级视图上,然后让它DontDestroyOnLoad(1)。初始化字典(2)、找到各节点并把此脚本所在的_UIManager物体放到_ScriptMgr节点下都是次要的,其中“各节点”指Canvas画布中的Normal、Fixed、Pop、_ScriptMgr(3),初始化窗体路径字典集合(4)
        {   //(1)
            //GameObject  myCanvas=ResourcesMgr.GetInstance().LoadAsset("Canvas",true);
            GameObject myCanvas = ResourcesMgr.GetInstance().LoadAsset(SystemDefine.SYS_Canvas_Path, false);
            DontDestroyOnLoad(myCanvas);         
            //(2)
            _DicUIFormPaths = new Dictionary<string, string>();             //窗体名|路径(窗体预设体在Resources文件夹下的)
            _DicAllUIForms = new Dictionary<string, BaseUIForm>();          //窗体名|窗体类  (每个窗体预设体都挂有一个继承自BaseUIForm、和窗体同名的类)      
            _DicCurrentShowUIForms = new Dictionary<string, BaseUIForm>();  //窗体名|窗体类
            _StaCurrentShowUIForms = new Stack<BaseUIForm>();
            //(3)
            traCanvas = GameObject.Find("Canvas(Clone)").transform;
            traNormal = traCanvas.Find(SystemDefine.SYS_NormalNodeName);
            traFixed = traCanvas.Find(SystemDefine.SYS_FixedNodeName);
            traPopup = traCanvas.Find(SystemDefine.SYS_PopupNodeName);
            traUIScript = traCanvas.Find(SystemDefine.SYS_ScriptMgrNodeName);
            transform.SetParent(traUIScript);
            //(4)
            if (_DicUIFormPaths != null)
            {

                //_DicUIFormPaths.Add("LogonUIForm", "UIPrefabs/LogonUIForm");
                //_DicUIFormPaths.Add("SelectHeroUIForm", "UIPrefabs/SelectHeroUIForm");
                //_DicUIFormPaths.Add("MainCityUIForm", "UIPrefabs/MainCityUIForm");
                //_DicUIFormPaths.Add("HeroInfoUIForm", "UIPrefabs/HeroInfoUIForm");
                //_DicUIFormPaths=ConfigManagerByJson("Json/UIFormsConfigInfo");

                //ConfigManagerByJson configManagerByJsonObj = new ConfigManagerByJson("UIFormsConfigInfo");
                //_DicUIFormPaths = configManagerByJsonObj.AppSetting;

                //路径字典集合,Json数据载入
                Init_DicUIFormPaths_Data();


            }
            //transform.localScale = Vector3.one;

        }

        #region 打开窗体 系列方法
        /// <summary>
        /// 打开窗体方法
        /// </summary>
        /// <param name="uiFormName"></param>
        public void ShowUIForm(string uiFormName)//首要任务,把窗体预设体载入(1)、挂好(2)(顺便将其先隐藏(3),加入所有窗体缓存集合(4))其次,根据窗体显示模式,进行不同的操作(5)
        {
           
            BaseUIForm wanttedUIForm = null;
            //参数检查,看窗体的名字是否为空
            if (string.IsNullOrEmpty(uiFormName))
            {
                Debug.Log("名字为空");
                return;
            }
            
            wanttedUIForm = LoadUIFormToAllFormsCache(uiFormName);
            if (wanttedUIForm == null) return;

            //如果UIType脚本中,IsClearStack为true,说明要进行清空栈操作
            if (wanttedUIForm.CurrentUIType.IsClearStack == true)
            {
                ClearStackArray();
            }
            //(5)
            switch (wanttedUIForm.GetComponent<BaseUIForm>().CurrentUIType.UIForm_ShowMode)
            {
                case UIFormShowMode.Normal:
                    //wanttedUIForm.gameObject.SetActive(true);
                    LoadUIFormToCurrentShowUIForm(uiFormName);
                    break;
                case UIFormShowMode.ReverseChange:
                    PushWanttedFormToStack(uiFormName);
                    break;
                case UIFormShowMode.HideOther:
                    ShowUIForm_HideOther(uiFormName);
                    break;
            }

        }
        /// <summary>
        /// 从缓存集合里得到窗体——即如果缓存集合中有此窗体直接返回,没有就去加载
        /// </summary>
        /// <param name="uiFormName"></param>
        /// <returns></returns>
        public BaseUIForm LoadUIFormToAllFormsCache(string uiFormName)//加载完第一遍后,它不用时就隐藏——需要加载第二遍时,直接从所有缓存集合中取,不需要重新加载了
        {
            BaseUIForm tempUIForm = null;
            _DicAllUIForms.TryGetValue(uiFormName, out tempUIForm);
            if(tempUIForm==null)
            {
                tempUIForm = LoadUIForm(uiFormName);
            }          
            return tempUIForm;
        }
        /// <summary>
        /// 纯加载
        /// </summary>
        /// <param name="uiFormName"></param>
        /// <returns></returns>
        /// 
        public BaseUIForm LoadUIForm(string uiFormName)
        {
            //由窗体名字的得到路径,通过路径载入窗体(1);其次,根据窗体的位置信息,把它挂好(2)(顺便把新窗体隐掉(3),加入“所有UI窗体缓存集合”(4))。
            BaseUIForm tempUIForm=null;
            string uiFormPath = null;
            GameObject prefabClone = null;
            //(1)
            _DicUIFormPaths.TryGetValue(uiFormName, out uiFormPath);
            if (!string.IsNullOrEmpty(uiFormPath))
            {
                prefabClone = ResourcesMgr.GetInstance().LoadAsset(uiFormPath, false);
                if(prefabClone!=null)                       
            #region //载入,及可能的异常
                {
                    tempUIForm = prefabClone.GetComponent<BaseUIForm>();//动态多态性,得到的是具体的窗体类
                    if(tempUIForm)
                    {//(2)
                        switch (tempUIForm.CurrentUIType.UIForm_Pos)
                        {
                            case UIFormPos.Normal:
                                tempUIForm.transform.SetParent(traNormal,true);
                                break;
                            case UIFormPos.Fixed:
                                tempUIForm.transform.SetParent(traFixed,true);
                                break;
                            case UIFormPos.Popup:
                                tempUIForm.transform.SetParent(traPopup,true);                               
                                break;
                        }
                        //(3)
                        tempUIForm.gameObject.SetActive(false);
                        //(4)
                        _DicAllUIForms.Add(uiFormName, tempUIForm);
                    }
                    else
                    {
                        Debug.Log("克隆体的原物体上,未挂脚本。克隆体的名称是:"+prefabClone.name);
                    }
                }   
                else
                {
                    Debug.Log("在该位置找不到预设体");//路径字符串错了,或正确字符串下没放预设体
                }
                #endregion
            }
            else
            {
                Debug.Log("路径缓存集合中,此名字的路径不存在");//窗体名字写错了,或者正确名字下,Json中路径Value是空的。
            }
 
            return tempUIForm;
        }
        /// <summary>
        ///  添加到“_DicCurrentShowUIForm”集合   (窗体类是从“_DicAllUIForms”中获取的)(并让窗体显示),事先 检查“当前显示UIForm集合”是否初始化,进一步检查“当前显示UIForm集合”是否有它(另检查<所有UI窗体集合>中是否有该窗体类)
        /// </summary>
        /// <param name="uiFormName"></param>
        public void LoadUIFormToCurrentShowUIForm(string uiFormName)
        {
            //我自己写的
            //BaseUIForm tempUIForm=null;
            //if(_DicCurrentShowUIForm!=null)
            //{
            //    BaseUIForm tempUIForm1 = null;
            //    if( _DicCurrentShowUIForm.TryGetValue(uiFormName,out tempUIForm1))
            //    {
            //        Debug.Log("<当前显示窗体>集合中已经有该元素,不需要重新添加");
            //        return;
            //    }             

            //    if (_DicAllUIForms.TryGetValue(uiFormName, out tempUIForm))
            //    {
            //        _DicCurrentShowUIForm.Add(uiFormName, tempUIForm);
            //    }
            //    else
            //    {
            //        Debug.Log("<所有UI窗体>集合中没有这个窗体类");
            //    }
            //}
            //else
            //{
            //    Debug.Log("<当前显示窗体集合>不存在或者没有初始化");
            //}

            //原先简化的
            if (_DicCurrentShowUIForms == null)
            {
                Debug.Log("_DicCurrentShowUIForm没有初始化");
                return;
            }
            BaseUIForm baseUIForm = null;
            if (_DicCurrentShowUIForms.TryGetValue(uiFormName, out baseUIForm))
            {
                Debug.Log("_DicCurrentShowUIForm已经添加了此窗体类");
               // baseUIForm.Display();
                return;
            }
            BaseUIForm tempUIForm = null;
            if (!_DicAllUIForms.TryGetValue(uiFormName, out tempUIForm))
            {
                Debug.Log("_DicAllUIForms不存在这个窗体类");
                return;
            }
            tempUIForm.Display();
            _DicCurrentShowUIForms.Add(uiFormName, tempUIForm);
            
        }
        /// <summary>
        /// 窗体入栈    事先冻结栈中窗体的栈顶元素窗体(1),从“_DicAllUIForms”找到要显示的UI窗体后,把它加入当前显示栈中,并显示(2)——不需要加入当前显示缓存集合吗?
        /// </summary>
        /// <param name="uiFormName"></param>
        public void PushWanttedFormToStack(string uiFormName)
        {
            if(_StaCurrentShowUIForms.Count>1)
            {
               BaseUIForm topFormClassInStack= _StaCurrentShowUIForms.Peek();
                topFormClassInStack.Freeze();//里面的秒表计数器等等,都停止?
            }
            BaseUIForm newUIForm = null;
            if(_DicAllUIForms.TryGetValue(uiFormName,out newUIForm))
            {
                _StaCurrentShowUIForms.Push(newUIForm);
                newUIForm.Display();
            }
            else
            {
                Debug.Log("所有窗体集合中,找不到这个类");
            }
            
        }
        /// <summary>
        /// 隐藏其它窗体的打开:把普通窗体_DicCurrentShowUIForm集合、反向切换窗体_StaCurrentShowUIForm,这两个集合中的窗体统统关闭——然后,把要显示的窗体放到_DicCurrentShowUIForm集合中+显示(2),事先检查该窗体是否已经显示过了,已显示就不再往当前显示集合_DicCurrentShowUIForm里放了(1)
        /// </summary>
        public void ShowUIForm_HideOther(string uiFormName)
        {
            BaseUIForm wannaShowForm = null;
            BaseUIForm wannaShowFormInAllFormsDic = null;
            //事先检查该窗体是否已经显示过了,已显示就不再往当前显示集合_DicCurrentShowUIForm里放了(1)
            _DicCurrentShowUIForms.TryGetValue(uiFormName,out wannaShowForm);
            if(wannaShowForm)
            {

                Debug.Log("已经显示过了");
                return;
            }
            //把普通窗体_DicCurrentShowUIForm集合、反向切换窗体_StaCurrentShowUIForm,这两个集合中的窗体统统关闭——然后,把要显示的窗体放到_DicCurrentShowUIForm集合中+显示(2)
            foreach (BaseUIForm baseUIForm in _DicCurrentShowUIForms.Values)
            {
                baseUIForm.Hide();
            }
            foreach(BaseUIForm baseUIForm in _StaCurrentShowUIForms)
            {
                baseUIForm.Hide();
            }
            _DicAllUIForms.TryGetValue(uiFormName,out wannaShowFormInAllFormsDic);
            _DicCurrentShowUIForms.Add(uiFormName,wannaShowFormInAllFormsDic);
            wannaShowFormInAllFormsDic.Display();
        }
        private bool ClearStackArray()//不同窗体切换引发混乱?
        {
            if(_StaCurrentShowUIForms!=null&&_StaCurrentShowUIForms.Count>1)
            {
                _StaCurrentShowUIForms.Clear();
                return true;
            }
            return false;
        }
        #endregion


        #region 关闭窗体 系列方法
        /// <summary>
        /// 关闭窗体:
        ///          根据窗体的不同显示类型,进项操作(2)
        ///          事先进行参数检查:字符换是否为空+是否加入所有窗体缓存(1)
        /// </summary>
        /// <param name="uiFormName"></param>
        public void CloseUIForm(string uiFormName)
        {
            BaseUIForm wannaCloseForm=null;
            if (string.IsNullOrEmpty(uiFormName))
            {
                Debug.Log("名字为空");
                return;
            }
            if (!_DicAllUIForms.TryGetValue(uiFormName, out wannaCloseForm))
            {
                Debug.Log("想要关闭的窗体在_DicAllUIForms中不存在,请检查名字,如果名字正确请检查Json中元素" + uiFormName);
                return;
            }
            else
            {
                switch(wannaCloseForm.CurrentUIType.UIForm_ShowMode)
                {
                    case UIFormShowMode.Normal:
                        CloseUIForm_Normal(uiFormName);
                        break;
                    case UIFormShowMode.ReverseChange:
                        CloseUIForm_ReverseChange();
                        break;
                    case UIFormShowMode.HideOther:
                        CloseUIForm_HideOther(uiFormName);
                        break;
                }
            }

        }//Method_end
        /// <summary>
        /// 普通窗体的关闭:
        ///                
        /// </summary>
        /// <param name="uiFormName"></param>
        public void CloseUIForm_Normal(string uiFormName)
        {
            BaseUIForm wannaCloseForm = null;
            if(!_DicCurrentShowUIForms.TryGetValue(uiFormName, out wannaCloseForm))
            {
                Debug.Log("想要关闭的窗体在_DicCurrentShowUIForm中不存在,请检查Json中元素" + uiFormName);
            }
            else
            {
                _DicCurrentShowUIForms.Remove(uiFormName);
                wannaCloseForm.Hide();

            }

        }
        /// <summary>
        /// 反向切换窗体的关闭:
        ///                    如果栈中只有1个,直接出栈,并隐藏;
        ///                    如果栈中有2个以上,出栈+并隐藏后,取得栈顶元素,显示
        ///                    
        /// </summary>
        /// <param name="uiFormName"></param>
        public void CloseUIForm_ReverseChange()//没有参数吗?
        {
            if(_StaCurrentShowUIForms.Count>=2)
            {
                BaseUIForm wannaCloseForm = _StaCurrentShowUIForms.Pop();
                wannaCloseForm.Hide();
                BaseUIForm topFormInStack= _StaCurrentShowUIForms.Peek();
                topFormInStack.Replay();
            }
            else if(_StaCurrentShowUIForms.Count == 1)
            {
                BaseUIForm wannaCloseForm=_StaCurrentShowUIForms.Pop();
                wannaCloseForm.Hide();

            }
        }//Method_end
        /// <summary>
        /// 隐藏其它窗体的关闭:把它从当前显示窗体集合中找出来,隐藏并移出集合+先前Show的时候关掉的两个集合重新显示
        /// </summary>
        public void CloseUIForm_HideOther(string uiFormName)
        {
            //把窗体类从当前显示UI集合中移除,让该集合中元素都显示;
            BaseUIForm wannaCloseForm = null;
            _DicCurrentShowUIForms.TryGetValue(uiFormName,out wannaCloseForm);
            if (!wannaCloseForm)
            {
                Debug.Log("当前显示窗体集合中,没有此窗体" + uiFormName);
                return;
            }
            wannaCloseForm.Hide();
            _DicCurrentShowUIForms.Remove(uiFormName);
            foreach(BaseUIForm baseUIForm in _DicCurrentShowUIForms.Values)
            {
                baseUIForm.Replay();
            }
            foreach(BaseUIForm baseUIForm in _StaCurrentShowUIForms)
            {
                baseUIForm.Replay();
            }
            //此时不一定有 反向切换窗体在显示啊
        }
        #endregion

        #region 显示“UIManager”核心数据,供测试使用
        //显示所有窗体的数量
        public int ShowAllUIFormsCount()
        {
            if(_DicAllUIForms!=null)
            {
                return _DicAllUIForms.Count;
            }
            else
            {
                return 0;
            }

        }
        //显示“当前显示窗体”的数量
        public int Show_DicCurrentShowUIFormsCount()
        {
            if (_DicCurrentShowUIForms != null)
            {
                return _DicCurrentShowUIForms.Count;
            }
            else
            {
                return 0;
            }

        }
        //显示栈里窗体的数量
        public int Show_StackCurrentShowUIFormsCount()
        {
            if (_StaCurrentShowUIForms != null)
            {
                return _StaCurrentShowUIForms.Count;
            }
            else
            {
                return 0;
            }

        }
        #endregion
        //路径字典集合,Json数据载入
        private void Init_DicUIFormPaths_Data()
        {
            ConfigManagerByJson configManagerByJson = new ConfigManagerByJson(SystemDefine.SYS_JsonName_path);
            if(configManagerByJson!=null)
            {
                _DicUIFormPaths=configManagerByJson.AppSetting;
            }
        }

    }//Class_end
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值