自己参照网上的UI框架,简单改了下,并且用到了昨天的txt文本读取。只做了个简单的测试,可能存在一些问题。
工具类代码
首先在Unity中新建3个C#脚本,分别命名为GameRoot,UIBase,UIManager,命名看自己喜好吧。分别如下:
UIBase:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIBase : MonoBehaviour {
/// <summary>
/// 显示界面
/// </summary>
public virtual void DoOnEntering() { }
/// <summary>
/// 暂停界面
/// </summary>
public virtual void DoOnPausing() { }
/// <summary>
/// 继续界面
/// </summary>
public virtual void DoOnResuming() { }
/// <summary>
/// 关闭界面
/// </summary>
public virtual void DoOnExiting() { }
}
UIManager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIManager {
/// <summary>
/// 单例模式,初始化对象
/// </summary>
private static UIManager _instance;
public static UIManager Instance
{
get
{
if (_instance == null)
{
_instance = new UIManager();
}
return _instance;
}
}
//构造函数中初始化,读取UI文件夹下的所有prefabs
private UIManager()
{
LoadAllUIPrefabs();
}
/// <summary>
/// 存放UI面板的栈
/// </summary>
private Stack<UIBase> UIPanelStack;
/// <summary>
/// 保存所有的面板
/// </summary>
private Dictionary<string, UIBase> UIPanelDict;
/// <summary>
/// 根据名字保存面板的prefab
/// </summary>
private Dictionary<string, GameObject> UIPrefabDict =new Dictionary<string, GameObject>();
/// <summary>
/// UI路径
/// </summary>
private string ResourceDir = "UI";
/// <summary>
/// 把页面入栈--把页面显示在界面上
/// </summary>
public void PushPanel(string UIPanelName)
{
if (UIPanelStack == null)
UIPanelStack = new Stack<UIBase>();
//判断一下栈里面是否有页面
if (UIPanelStack.Count > 0)
{
UIBase topPanel = UIPanelStack.Peek();
topPanel.DoOnPausing();
}
UIBase panel = GetPanel(UIPanelName);
panel.DoOnEntering();
UIPanelStack.Push(panel);
}
/// <summary>
/// 出栈 ,把页面从界面上移除
/// </summary>
public void PopPanel()
{
if (UIPanelStack == null)
UIPanelStack = new Stack<UIBase>();
if (UIPanelStack.Count == 0) return;
//关闭栈顶页面的显示
UIBase topPanel = UIPanelStack.Pop();
topPanel.DoOnExiting();
if (UIPanelStack.Count > 0)
{
UIBase topPanel2 = UIPanelStack.Peek();
topPanel2.DoOnResuming();
}
}
/// <summary>
/// 根据面板类型 得到实例化的面板
/// </summary>
/// <returns></returns>
private UIBase GetPanel(string UIPanelName)
{
if (UIPanelDict == null)
{
UIPanelDict = new Dictionary<string, UIBase>();
}
UIBase panel;
UIPanelDict.TryGetValue(UIPanelName, out panel);
//如果找不到,就根据prefab去实例化面板
if (panel == null)
{
GameObject UIPrefab = UIPrefabDict[UIPanelName];
GameObject instPanel = GameObject.Instantiate<GameObject>(UIPrefab);
instPanel.name = UIPanelName;
UIBase UIBase = instPanel.GetComponent<UIBase>();
UIPanelDict.Add(UIPanelName, UIBase);
return UIBase;
}
else
{
return panel;
}
}
//加载prefab的方法,存到字典中
public void LoadAllUIPrefabs()
{
TextAsset ta = Resources.Load<TextAsset>("UIPanelInfo");
string allInfo = ta.text;
string[] lineInfoArray = allInfo.Split('\n');
foreach (string lineInfo in lineInfoArray)
{
string[] itemInfoArray = lineInfo.Split(',');
foreach (string item in itemInfoArray)
{
string UIPath = ResourceDir + "/" + item;
GameObject UIPrefab = Resources.Load<GameObject>(UIPath);
if (UIPrefab)
UIPrefabDict.Add(item, UIPrefab);
}
}
}
}
GameRoot:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameRoot : MonoBehaviour {
/// <summary>
/// 启动初始界面,挂在游戏物体之上
/// </summary>
void Start () {
UIManager.Instance.PushPanel("OptionPanel");
}
}
使用方法
简单测试Demo:
在Assets文件夹下新建Resources,Scripts,Scenes和UIFramework文件夹,Rescources文件夹下新建UI文件夹和UIPanelInfo.txt文件(UTF-8格式)。Hierarchy面板新建两个Canvas,改名为OptionPanel和StartPanel,在各自下面分别再建一个Panel,改改颜色大小之类的。OptionPanel下新建一个Start按钮。再新建两个脚本StartUI和OptionUI,都继承自UIBase,之后就可以复写父类的四个方法,分别可以控制UI面板的各个状态。OptionUI在添加一个点击事件–事件内容为push一个StartPanel,之后给Start按钮添加点击事件。
txt文本填写StartPanel,OptionPanel
具体格式和昨天的一样,也可以选择用json之类的
上面只是试了下,因为blog实在写不了太多,太废时间了,具体怎么用,我可能会出个视频,也加强下自己对这个工具类的理解。其实如果UI面板比较少的话,没必要用框架,不过用了的话,整体确实清晰很多,也方便管理。
今天,到这了。