记录最新学习的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框架的学习使用过程,欢迎大佬进行指正!