UI框架搭建DAY2

今天的主要任务是完善NormalPanel, 搭建PopupPanel。

在编写PanelManager的过程中,发现了一个bug。昨天把panelPath直接传给了ResourceManager.GetInstance().LoadAsset<GameObject>(path);

今天做了修改,并且添加了初始化dictPanelPath的方法,为此在SysDefine新添加了一个类,PanelNameStr。在Helper类里添加了以一个方法GetPathByName。

 

部分修改代码如下,偷了个懒,直接全部复制粘贴了:

PanelManager.cs

  1 /*
  2         2018.12.30修改记录:1.增加了SetDictPanelPath()方法
  3                             2.修改了CreatePanel()方法
  4                             3.增加了DestroyPanel()方法
  5 */
  6 using System.Collections.Generic;
  7 using UnityEngine;
  8 public class PanelManager
  9 {
 10     //本类实例
 11     private static PanelManager _instance;
 12     //存储面板名字和对应的路径字典
 13     public static Dictionary<string, string> dictPanelPath;
 14     //存储已显示的面板字典
 15     public static Dictionary<string, BasePanel> dictCurPanel;
 16     //存储已隐藏的面板字典
 17     public static Dictionary<string, BasePanel> dictHidePanel;
 18     //存储Popup类型面板的字典
 19     public static Dictionary<string, Stack<BasePanel>> dictPopupPanel;
 20 
 21     //单例模式
 22     private PanelManager() { }
 23     public static PanelManager GetInstance()
 24     {
 25         if(_instance == null)
 26         {
 27             _instance = new PanelManager();
 28 
 29             InitProperties();
 30             SetDictPanelPath();
 31         }
 32         return _instance;
 33     }
 34     //初始化字段
 35     private static void InitProperties()
 36     {
 37         dictPanelPath = new Dictionary<string, string>();
 38         dictCurPanel = new Dictionary<string, BasePanel>();
 39         dictHidePanel = new Dictionary<string, BasePanel>();
 40         dictPopupPanel = new Dictionary<string, Stack<BasePanel>>();
 41     }
 42     private static void SetDictPanelPath()
 43     {
 44         dictPanelPath.Add(PanelNameStr.LogOnPanel, PrefabPathStr.logOnPanelPath);
 45         dictPanelPath.Add(PanelNameStr.RegisterPanel, PrefabPathStr.registerPanelPath);
 46     }
 47     /// <summary>
 48     /// 创建一个面板
 49     /// 先检查dictHidePanel集合里是否存在此面板,有则取出,显示,并加入dictCurPanel集合
 50     /// 没有,则创建一个,然后加如dictCurPanel集合。
 51     /// </summary>
 52     /// <param name="panelName">要创建的面板的名字</param>
 53     /// <returns></returns>
 54     public BasePanel CreatePanel(string panelName)
 55     {
 56         BasePanel basePanel = null;        
 57         dictHidePanel.TryGetValue(panelName, out basePanel);
 58         if(basePanel != null)
 59         {
 60             basePanel.Open();
 61             //添加到正在显示的面板集合
 62             dictCurPanel.Add(panelName, basePanel);
 63             return basePanel;
 64         }
 65         else
 66         {
 67 
 68             string path = Helper.GetInstance().GetPathByName(panelName);
 69 
 70            //根据存储路径,加载预制体
 71             GameObject go = ResourceManager.GetInstance().LoadAsset<GameObject>(path);
 72             if(go != null)
 73             {
 74                 basePanel = go.GetComponent<BasePanel>();
 75                 if(basePanel != null)
 76                 {
 77                     //添加到正在显示的面板集合
 78                     dictCurPanel.Add(panelName, basePanel);
 79                 }
 80                 else
 81                 {
 82                     Debug.LogError(GetType()+"你可能忘记挂载了BasePanel类型的脚本");
 83                 }
 84                 return basePanel;
 85             }
 86             else
 87             {
 88                 Debug.Log(GetType()+"请检查配置文件,预制体不存在");
 89 
 90             }
 91         }
 92         return null;
 93     }
 94 
 95     /// <summary>
 96     /// 1.从dictCurPanel集合中取出对应的面板
 97     /// 2.隐藏
 98     /// 3.加入dictHidePanel集合
 99     /// </summary>
100     /// <param name="PanelName"></param>
101     public void DestroyPanel(string panelName)
102     {
103         BasePanel basePanel = null;
104         basePanel = dictCurPanel[panelName];
105         if(basePanel == null)
106         {
107             Debug.LogError(GetType()+"面板不存在,请检查配置文件");
108             return;
109         }
110         else
111         {
112             //关闭面板
113             basePanel.Close();
114             //加入dictHidePanel集合
115             dictHidePanel.Add(panelName, basePanel);
116         }
117     }
118 
119 }

为了测试DestroyPanel,新建了一个面板RegisterPanel。

在LogOnPanel.cs类里测试

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 
 5 public class LogOnPanel : BasePanel
 6 {
 7     private void Awake()
 8     {
 9         this.panelType = EPanelType.Normal;
10     }
11 
12     
13     public void OnStartGameBtnClick()
14     {
15         //TO DO
16     }
17     //测试DestroyPanel()方法
18     public void OnRegisterBtnClick()
19     {
20         //隐藏自身
21         PanelManager.GetInstance().DestroyPanel(PanelNameStr.LogOnPanel);
22         //显示注册面板
23         PanelManager.GetInstance().CreatePanel(PanelNameStr.RegisterPanel);
24     }
25 
26 }

另外在设计过程中和最初的想法有些出入,本来打算用工厂方法模式成产各种类型的Panel,现在类型已经在Awake方法里注册了,而且也不麻烦,所以把NormalPanel.cs,PopupPanel.cs,HideOtherPanel.cs删除了,我要去学习Shader了,下午继续更PopupPanel的搭建。

就在我光顾“五谷轮回之所”的时候想到我的代码还有一个严重的Bug,对象池技术中有生有死,有死有生,相互转化。而我的代码做了形式上的转化,却没有做内存处理。当从隐藏面板集合中取出一个面板显示的时候,就是由死转化到生,需要做两个处理,一是从dictHidePanel中移除这个键值对,而是向dictCurPanel中加入这个键值对。同理,当从当前显示面板中取出一个面板隐藏时,就是由生到死,也需要做对应的两个处理。修改代码如下:

1  //添加到正在显示的面板集合
2             dictCurPanel.Add(panelName, basePanel);
3             //从dictHidePanel集合中移除
4             dictHidePanel.Remove(panelName);

这是CreatePane()方法中修改的代码。

1 //从dictCurPanel集合中移除
2             dictCurPanel.Remove(panelName);
3             //加入dictHidePanel集合
4             dictHidePanel.Add(panelName, basePanel);

这是DestroyPanel()方法中修改的代码。

 

posted @ 2018-12-30 11:08  _清风明月  阅读(281)  评论(0编辑  收藏  举报