作用:统一管理UI面板的显示相关
资源加载模块
BasePanel.CS
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/// <summary>
/// 面板基类
/// 方便通过代码快速找到所有自己面板下的控件对象,然后在子类中实现相关逻辑
/// </summary>
/// <typeparam name="T"></typeparam>
public class BasePanel : MonoBehaviour
{
//通过里式转换原则 来存储所有的控件
private Dictionary<string, List<UIBehaviour> > controlDic = new Dictionary<string, List<UIBehaviour>>();
void Awake ()
{
//找到自己所需要的控件
FindChildrenControl<Button>();
FindChildrenControl<Image>();
FindChildrenControl<Toggle>();
FindChildrenControl<Text>();
FindChildrenControl<Slider>();
FindChildrenControl<ScrollRect>();
}
/// <summary>
/// 得到对应名字的对应控件脚本
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="controlName"></param>
/// <returns></returns>
protected T GetControl<T>(string controlName) where T : UIBehaviour
{
if (controlDic.ContainsKey(controlName))
{
for (int i = 0; i < controlDic[controlName].Count; i++)
{
if (controlDic[controlName][i] is T)
{
return controlDic[controlName][i] as T;
}
}
}
return null;
}
/// <summary>
/// 找到子对象的对应控件
/// </summary>
/// <typeparam name="T"></typeparam>
private void FindChildrenControl<T>() where T:UIBehaviour
{
T[] controls = this.GetComponentsInChildren<T>();
string gobjName;
for (int i = 0; i < controls.Length; i++)
{
gobjName = controls[i].gameObject.name;
if (controlDic.ContainsKey(gobjName))
{
controlDic[gobjName].Add(controls[i]);
}
else
{
controlDic.Add(gobjName, new List<UIBehaviour>() { controls[i] });
}
}
}
}
测试
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TestUIobj : BasePanel
{
void Start()
{
GetControl<Button>("Button1").onClick.AddListener(ClickBtn1);
GetControl<Button>("Button2").onClick.AddListener(ClickBtn2);
GetControl<Button>("Button3").onClick.AddListener(ClickBtn3);
}
public void ClickBtn1()
{
Debug.Log("点击Button1");
}
public void ClickBtn2()
{
Debug.Log("点击Button2");
}
public void ClickBtn3()
{
Debug.Log("点击Button3");
}
}
UI管理器,控制面板。
UIMgr .CS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// UI层级枚举
/// </summary>
public enum E_UI_Layer
{
Bot,
Mid,
Top,
System,
}
/// <summary>
/// UI管理器
/// 1.管理所有显示的面板
/// 2.提供给外部 显示和隐藏等等接口
/// </summary>
public class UIMgr : BaseMgr<UIMgr>
{
public Dictionary<string, BasePanel> panelDic = new Dictionary<string, BasePanel>();
private Transform bot;
private Transform mid;
private Transform top;
private Transform system;
public UIMgr()
{
//创建Canvas 让其过场景的时候不被移除
GameObject obj = ResManager.instance.Load<GameObject>("UI/Canvas");
Transform canvas = obj.transform;
GameObject.DontDestroyOnLoad(obj);
//找到各层
bot = canvas.Find("bot");
mid = canvas.Find("mid");
top = canvas.Find("top");
system = canvas.Find("system");
//创建EventSystem 让其过场景的时候不被移除
obj = ResManager.instance.Load<GameObject>("UI/EventSystem");
GameObject.DontDestroyOnLoad(obj);
}
/// <summary>
/// 显示面板
/// </summary>
/// <typeparam name="T">面板脚本类型</typeparam>
/// <param name="PanelName">面板名</param>
/// <param name="layer">显示在哪一层</param>
/// <param name="callback">当面板预设体创建成功后 想要做的事</param>
public void ShowPanel<T>(string PanelName, E_UI_Layer layer = E_UI_Layer.Mid,UnityAction<T> callback=null) where T:BasePanel
{
if (panelDic.ContainsKey(PanelName))
{
//处理面板创建完成后的逻辑
if (callback != null)
{
callback(panelDic[PanelName] as T);
}
}
ResManager.instance.LoadAsyn<GameObject>("UI/" + PanelName, (obj) =>
{
//把他作为Canvas的子对象
//并且要设置它的相对位置
//找到父对象 到底在哪一层
Transform father = bot;
switch (layer)
{
case E_UI_Layer.Mid:
father = mid;
break;
case E_UI_Layer.Top:
father = top;
break;
case E_UI_Layer.System:
father = system;
break;
}
//设置父对象 设置相对位置和大小
obj.transform.SetParent(father);
obj.transform.localScale = Vector3.one;
(obj.transform as RectTransform).offsetMax = Vector2.zero;
(obj.transform as RectTransform).offsetMin = Vector2.zero;
//得到预设体身上的面板脚本
T panel = obj.GetComponent<T>();
//处理面板创建完成后的逻辑
if (callback != null)
{
callback(panel);
return;
}
//把面板存起来
panelDic.Add(PanelName, panel);
});
}
/// <summary>
/// 隐藏面板
/// </summary>
/// <param name="PanelName"></param>
public void HidePanel(string PanelName)
{
if (panelDic.ContainsKey(PanelName))
{
GameObject.Destroy(panelDic[PanelName].gameObject);
panelDic.Remove(PanelName);
}
}
}
测试
将Canvas与EventSystem制作成预制体
canvas下的层级
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StartPanel : MonoBehaviour
{
void Start()
{
UIMgr.instance.ShowPanel<FirstUItest>("FirstPanel",E_UI_Layer.Mid, ShowPanelOver);
// Invoke("DelayHide", 3);
}
private void ShowPanelOver(FirstUItest panel)
{
panel.InitInfo();
}
//private void DelayHide()
//{
// UIMgr.instance.HidePanel("FirstPanel");
//}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FirstUItest : BasePanel
{
void Start()
{
GetControl<Button>("BtnStart").onClick.AddListener(ClickStart);
}
public void ClickStart()
{
Debug.Log("点击了开始");
UIMgr.instance.ShowPanel<GameMains>("MainGame");
}
public void InitInfo()
{
Debug.Log("面板实例化完成");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameMains : BasePanel
{
// Start is called before the first frame update
void Start()
{
GetControl<Button>("BtnBack").onClick.AddListener(ClickQuit);
}
public void ClickQuit()
{
UIMgr.instance.HidePanel("MainGame");
Debug.Log("返回到游戏开始界面");
}
}