UFL8——UI管理器的隐藏面板可选销毁优化
为什么要进行 隐藏面板可选销毁 优化
我们目前隐藏面板时,会直接将面板销毁,下次创建时再重新创建
- 优点:当存在内存压力时,直接销毁面板后,当内存不足时会触发GC,不会因为存在没有使用的面板引用而造成内存崩溃
- 缺点:会产生内存垃圾加快GC的触发,频繁的销毁创建会增加性能消耗
也就是说我们不能直接将面板隐藏改成不销毁,而应该改为可以让我们自己控制最好
我们可以根据项目的实际情况 选择性的使用失活或销毁
隐藏面板可选销毁实现
主要制作思路
无需使用缓存池,因为缓存池主要是提供给非唯一对象使用的,UI面板大部分情况下是唯一的,因此我们直接在UI管理器中修改逻辑即可
主要实现内容
- 隐藏面板时,可以选择销毁还是失活
- 显示面板时,如果存在直接激活,如果不存在再重新创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| private Dictionary<string, BasePanelInfo> panelDic = new Dictionary<string, BasePanelInfo>();
public void HidePanel<T>(bool isDestroy = false) where T : BasePanel { string panelName = typeof(T).Name; if (panelDic.ContainsKey(panelName)) { PanelInfo<T> panelInfo = panelDic[panelName] as PanelInfo<T>; if (panelInfo.panel == null) { panelInfo.isHide = true; panelInfo.callBack = null; } else { panelInfo.panel.HideMe(); if (isDestroy) { GameObject.Destroy(panelInfo.panel.gameObject); panelDic.Remove(panelName); } else panelInfo.panel.gameObject.SetActive(false); } } }
public void ShowPanel<T>(E_UILayer layer = E_UILayer.Middle, UnityAction<T> callBack = null, bool isSync = false) where T : BasePanel { string panelName = typeof(T).Name; if (panelDic.ContainsKey(panelName)) { PanelInfo<T> panelInfo = panelDic[panelName] as PanelInfo<T>; if (panelInfo.panel == null) { panelInfo.isHide = false; if (callBack != null) panelInfo.callBack += callBack; } else { if (panelInfo.panel.gameObject.activeSelf) panelInfo.panel.gameObject.SetActive(true); panelInfo.panel.ShowMe(); callBack?.Invoke(panelInfo.panel); } return; }
panelDic.Add(panelName, new PanelInfo<T>(callBack)); ABResManager.Instance.LoadResAsync<GameObject>("ui", panelName, (res) => { PanelInfo<T> panelInfo = panelDic[panelName] as PanelInfo<T>; if (panelInfo.isHide) { panelDic.Remove(panelName); return; } Transform layerObj = GetLayerObj(layer); if (layerObj == null) layerObj = middleLayer; GameObject panelObj = GameObject.Instantiate(res, layerObj, false); T panel = panelObj.GetComponent<T>(); panel.ShowMe(); panelInfo.panel = panel; panelInfo.callBack?.Invoke(panel); panelInfo.callBack = null; }, isSync); }
|
使用示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void Update() { if (Input.GetKeyDown(KeyCode.S)) { UIManager.Instance.ShowPanel<BeginPanel>(E_UILayer.System, (panel) => { panel.TestFun(); }); } if (Input.GetKeyDown(KeyCode.H)) { UIManager.Instance.HidePanel<BeginPanel>(); } }
|
按下H键隐藏面板时,面板不会销毁而是隐藏: