Unity基于进出栈的UI框架

萝らか妹 提交于 2019-11-30 00:33:39

本文是一个通过进出栈控制UI逻辑的小框架,原先一直以为挺难得,写了一遍之后感觉也不是那么难了,所以大家最好还是自己动手写一遍,相信我会收获很多东西的。

(有一件尴尬的事情,鉴于本人不会画什么逻辑图。。。。所以我就文字叙述了。。。)

 

那么,我们最开始先把准备工作做好,既然是UI的框架,那UI的基类肯定是必不可少的,这里只写了几个UI的基本状态

PanelBase

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class PanelBase : MonoBehaviour {
	public abstract void OnEnter();
	public abstract void OnPause();
	public abstract void OnResume();
	public abstract void OnExit();
}

下面我们需要一个PanelType类开存储UI的名字信息,我们是通过这个访问UI的

UIPanelType

public class UIPanelType 
{
	public const string MainMenu = "MainMenu";
	public const string LoadPanel = "LoadPanel";
}

在这里头我们通过Json文件加载UI的基本信息(名字、路径)

Json加载的方法请转到这个页面:https://blog.csdn.net/ztysmile/article/details/102724121

既然有了Json文件那么我们就要写对应的序列化类了,这里我们用一个数组存储

UIPanelInfo

[System.Serializable]
public class UIPanelInfo
{
	public string panelType;
	public string path;

	public UIPanelInfo(){}
}

UIPanelInfoList

using System.Collections.Generic;
[System.Serializable]
public class UIPanelInfoList
{
	public List<UIPanelInfo> panelInfoList;
	public UIPanelInfoList(){}
}

对应的Json文件内容如下:

{
    "panelInfoList":
    [
        {"panelType":"MainMenu","path":"MainMenuPanel"},
        {"panelType":"LoadPanel","path":"LoadPanel"}
    ]
}

 

现在基本的准备工作都做完了,下面就开始最重要的一个脚本,备注我尽可能的写的详细了,看不懂可以在问我的~~

UIPanelManager

using System.Collections.Generic;
using UnityEngine;

public class UIPanelManager 
{
	//单例
	public static UIPanelManager _instance;
	public static UIPanelManager Instance { get {
		if(_instance == null)
			{
				_instance = new UIPanelManager();
			}
			return _instance;
				} }
	//Canvas
	private Transform m_CanvasTransform;
	public Transform CanvasTransform { get
		{
			if (m_CanvasTransform == null)
			{
				m_CanvasTransform = GameObject.Find("Canvas").transform;
			}
			return m_CanvasTransform;
		}
	}

	//Panel路径字典,key:Name;Value:Path
	private Dictionary<string, string> m_PanelPathDict;
	//panel资源字典 key:Name;value:PanelBase
	private Dictionary<string, PanelBase> m_PanelDict;
	private Stack<PanelBase> m_PanelStack;

	private UIPanelManager()
	{
		ParseUIPanelTypeJson();
	}
	/// <summary>
	/// 放Panel
	/// </summary>
	/// <param name="panelType"></param>
	public void PushPanel(string panelType)
	{
		if(m_PanelStack == null)
		{
			m_PanelStack = new Stack<PanelBase>();
		}
		if (m_PanelStack.Count > 0)
		{
			PanelBase topPanel = m_PanelStack.Peek();
			topPanel.OnPause();
		}
		PanelBase panel = GetPanel(panelType);
		m_PanelStack.Push(panel);
		panel.OnEnter();
	}
	/// <summary>
	/// 弹出Panel
	/// </summary>
	public void PopPanel()
	{
		if(m_PanelStack == null)
		{
			m_PanelStack = new Stack<PanelBase>();
		}
		if (m_PanelStack.Count <= 0)
		{
			return;
		}
		PanelBase topPanel = m_PanelStack.Pop();
		topPanel.OnExit();

		if (m_PanelStack.Count > 0)
		{
			PanelBase panel = m_PanelStack.Peek();
			panel.OnResume();
		}

	}

	/// <summary>
	/// 得到Panel
	/// </summary>
	/// <param name="panelType"></param>
	/// <returns></returns>
	private PanelBase GetPanel(string panelType)
	{
		if (m_PanelDict == null)
		{
			m_PanelDict = new Dictionary<string, PanelBase>();
		}
		PanelBase panel = m_PanelDict.GetValue(panelType);

		if (panel == null)
		{
			string path = m_PanelPathDict.GetValue(panelType);
			GameObject go = GameObject.Instantiate(Resources.Load<GameObject>(path), CanvasTransform, false);
			panel = go.GetComponent<PanelBase>();
			m_PanelDict.Add(panelType,panel);
		}
		return panel;

	}
	/// <summary>
	/// 解析Json,将Panel信息添加到m_PanelPathDict字典中去
	/// </summary>
	private void ParseUIPanelTypeJson()
	{
		m_PanelPathDict = new Dictionary<string, string>();
		string path = "UIPanelTypeJson";
		string jsonText =JsonTool.ReadJsonText(path);
		UIPanelInfoList panelInfoList = JsonTool.LoadJsonData<UIPanelInfoList>(jsonText);
		foreach (UIPanelInfo UIPanelInfo in panelInfoList.panelInfoList)
		{
			Debug.Log(UIPanelInfo.panelType);
			m_PanelPathDict.Add(UIPanelInfo.panelType, UIPanelInfo.path);
		}
	}

}

其中字典的一个GetValue是加的一个扩展方法,其实就是字典的TryGetValue方法

public static Tvalue GetValue<Tkey, Tvalue>(this Dictionary<Tkey, Tvalue> dict, Tkey key)
	{
		Tvalue value = default(Tvalue);
		dict.TryGetValue(key, out value);
		return value;
	}

这样一个简单的小框架就完成了,激不激动~~

下面我们就可以根据我们的界面创建我们单独的Panel类然后继承PanelBase写相应的逻辑就可以了,每个页面之间也不会有太多的关联,改的时候也很方便了~~

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!