记录最新学习的UGUI框架。
UIType类保存面板基本信息(名称、路径),该面板会在具体的面板类里面(StartPanel)进行实例化。
public class UIType
{private string name;public string Name { get => name; }private string path;public string Path { get => path; }public UIType(string name,string path){this.name = name;this.path = path;}
}
BasePanel类为所有UI面板的基类
public class BasePanel
{public UIType uiType;/// <summary>/// 继承此类的具体物体/// </summary>public GameObject ActiveObj;public BasePanel(UIType uiType){this.uiType = uiType;}public virtual void OnStart(){Debug.LogError($"{uiType.Name}开始使用!");}public virtual void OnEnable(){}public virtual void OnDisable(){}public virtual void OnDestroy(){}
}
UIMehod为UI工具类
/// <summary>
/// UI工具类
/// </summary>
public class UIMehod
{private static UIMehod instance;public static UIMehod Instance{get{if (instance==null){instance = new UIMehod();}return instance;}}/// <summary>/// 获取场景中的Canvas画布/// </summary>/// <returns></returns>public GameObject FindCanvas(){GameObject go = GameObject.FindObjectOfType<Canvas>().gameObject;if (go==null){Debug.LogError("在此场景中没有找到Canvas");return go;}return go;}/// <summary>/// 根据名称查找父物体下面的子物体/// </summary>/// <param name="panel"></param>/// <param name="child_name"></param>/// <returns></returns>public GameObject FindObjectInChild(GameObject panel,string child_name){Transform[] transforms = panel.GetComponentsInChildren<Transform>();foreach (var item in transforms){if (item.gameObject.name.Equals(child_name)){return item.gameObject;}}Debug.LogError($"在{panel.name}下面没有查找到子物体{child_name}");return null;}/// <summary>/// 从目标物体上获取目标组件/// </summary>/// <typeparam name="T">要获取的组件</typeparam>/// <param name="Get_Obj"></param>/// <returns></returns>public T AddOrGetComponent<T>(GameObject Get_Obj)where T : Component{if (Get_Obj.GetComponent<T>()!=null){return Get_Obj.GetComponent<T>();}Debug.LogError($"无法在{Get_Obj}物体上获取目标组件");return null;}/// <summary>/// 从目标物体上根据子物体名称获取子物体并获取对应的组件/// </summary>/// <typeparam name="T">要获取的组件</typeparam>/// <param name="panel">目标物体(父物体)</param>/// <param name="ComponentName">要获取的子物体名称</param>/// <returns></returns>public T GetOrAddSingleComponentInChild<T>(GameObject panel,string ComponentName)where T : Component{Transform[] transforms = panel.GetComponentsInChildren<Transform>();foreach (var item in transforms){if (item.gameObject.name.Equals(ComponentName)){return item.gameObject.GetComponent<T>();}}Debug.LogError($"在{panel.name}父物体上没有找到名为{ComponentName}的子物体");return null;}
}
StartPanel类为开始面板类
public class StartPanel : BasePanel
{private static string name = "StartPanel";private static string path = "StartPanel";public static readonly UIType uIType = new UIType(path, name);public StartPanel():base(uIType){}public override void OnDestroy(){base.OnDestroy();}public override void OnDisable(){base.OnDisable();}public override void OnEnable(){base.OnEnable();}public override void OnStart(){//给StartPanel面板下UIMehod.Instance.GetOrAddSingleComponentInChild<Button>(ActiveObj, "Back").onClick.AddListener(() => { UIManager.Instance.Pop(false); });}
}
UIManager为UI控制类,UI面板会通过此类进行操作显示与隐藏
public class UIManager
{/// <summary>/// 存储UI面板的栈/// </summary>public Stack<BasePanel> Stack_UI;/// <summary>/// 存储UI面板的名称与我物体的字典/// </summary>public Dictionary<string, GameObject> Dic_UIObject;/// <summary>/// 当前场景对应的Canvas/// </summary>public GameObject CanvasObj;private static UIManager instance;public static UIManager Instance {get{if (instance==null){instance = new UIManager();}return instance;}}public UIManager(){//instance = this;Stack_UI = new Stack<BasePanel>();Dic_UIObject = new Dictionary<string, GameObject>();}/// <summary>/// 创建UI面板/// </summary>/// <param name="uiType"></param>/// <returns></returns>public GameObject GetSingleObject(UIType uiType){if (Dic_UIObject.ContainsKey(uiType.Name)){return Dic_UIObject[uiType.Name];}if (CanvasObj==null){CanvasObj = UIMehod.Instance.FindCanvas();}GameObject go = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>(uiType.Path), CanvasObj.transform);return go;}/// <summary>/// 入栈/// </summary>/// <param name="basePanel"></param>public void Push(BasePanel basePanel){if (Stack_UI.Count>0){//禁用栈顶的面板Stack_UI.Peek().OnDisable();}GameObject UI_Objecr = GetSingleObject(basePanel.uiType);Dic_UIObject.Add(basePanel.uiType.Name, UI_Objecr);basePanel.ActiveObj = UI_Objecr;if (Stack_UI.Count==0){Stack_UI.Push(basePanel);}else{if (Stack_UI.Peek().uiType.Name!=basePanel.uiType.Name){Stack_UI.Push(basePanel);}}basePanel.OnStart();Debug.Log($"{basePanel.uiType.Name}被Push入栈");}/// <summary>/// 出栈/// </summary>/// <param name="isLoad">是否清空栈(True:清空栈/// False:只弹出栈顶物体)</param>public void Pop(bool isLoad = false){if (isLoad==true){if (Stack_UI.Count>0){Stack_UI.Peek().OnDisable();Stack_UI.Peek().OnDestroy();//销毁栈顶面板并从字典中移除GameObject.Destroy(Dic_UIObject[Stack_UI.Peek().uiType.Name]);Dic_UIObject.Remove(Stack_UI.Peek().uiType.Name);Stack_UI.Pop();Pop(true);}}else{if (Stack_UI.Count>0){Stack_UI.Peek().OnDisable();Stack_UI.Peek().OnDestroy();//销毁栈顶面板并从字典中移除GameObject.Destroy(Dic_UIObject[Stack_UI.Peek().uiType.Name]);Dic_UIObject.Remove(Stack_UI.Peek().uiType.Name);Stack_UI.Pop();if (Stack_UI.Count > 0){///开启栈顶面板Stack_UI.Peek().OnEnable();}}}}
}
GameManager为游戏控制类,此类需要挂载到Unity场景中。此类有这个UI框架最基本的使用方法.
public class GameManager : MonoBehaviour
{private BasePanel Start_Panel = new StartPanel();public static GameManager Instance;private void Awake(){Instance = this;}private void Start(){DontDestroyOnLoad(this.gameObject);UIManager.Instance.CanvasObj = UIMehod.Instance.FindCanvas();UIManager.Instance.Push(Start_Panel);}private void Update(){if (Input.GetMouseButtonDown(0)){UIManager.Instance.Pop();}}
}
记录UI框架的学习使用过程,欢迎大佬进行指正!