UGUI框架
本套课程是学习的Siki学院的UI框架
1,新建一个工程 在Resource文件夹下的UIPanel文件夹下 创建几个UI的Prefab。
2, 编写UIPanelType脚本
using UnityEngine;
using System.Collections;
using System;
public enum UIPanelType {
ItemMessage,
Knapsack,
MainMenu,
Shop,
Skill,
System,
Task
}
3,编写json存储数据 Panel的存储路径和类型
{
"infoList":
[
{"panelTypeString":"ItemMessage",
"path":"UIPanel/ItemMessagePanel"},
{"panelTypeString":"Knapsack",
"path":"UIPanel/KnapsackPanel"},
{"panelTypeString":"MainMenu",
"path":"UIPanel/MainMenuPanel"},
{"panelTypeString":"Shop",
"path":"UIPanel/ShopPanel"},
{"panelTypeString":"Skill",
"path":"UIPanel/SkillPanel"},
{"panelTypeString":"System",
"path":"UIPanel/SystemPanel"},
{"panelTypeString":"Task",
"path":"UIPanel/TaskPanel"}
]
}
4,然后新建一个UIPaneInfo 序列化类型
using UnityEngine;
using System.Collections;
using System;
[Serializable]
public class UIPanelInfo :ISerializationCallbackReceiver {
[NonSerialized]
public UIPanelType panelType;
public string panelTypeString;
//{
// get
// {
// return panelType.ToString();
// }
// set
// {
// UIPanelType type =(UIPanelType)System.Enum.Parse(typeof(UIPanelType), value);
// panelType = type;
// }
//}
public string path;
// 反序列化 从文本信息 到对象
public void OnAfterDeserialize()
{
UIPanelType type = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);
panelType = type;
}
public void OnBeforeSerialize()
{
}
}
5,然后在新建UIManager脚本
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class UIManager {
///
/// 单例模式的核心
/// 1,定义一个静态的对象 在外界访问 在内部构造
/// 2,构造方法私有化
private static UIManager _instance;
public static UIManager Instance
{
get
{
if (_instance == null)
{
_instance = new UIManager();
}
return _instance;
}
}
private Transform canvasTransform;
private Transform CanvasTransform
{
get
{
if (canvasTransform == null)
{
canvasTransform = GameObject.Find("Canvas").transform;
}
return canvasTransform;
}
}
private Dictionary<UIPanelType, string> panelPathDict;//存储所有面板Prefab的路径
private Dictionary<UIPanelType, BasePanel> panelDict;//保存所有实例化面板的游戏物体身上的BasePanel组件
private Stack<BasePanel> panelStack;
private UIManager()
{
ParseUIPanelTypeJson();
}
/// <summary>
/// 把某个页面入栈, 把某个页面显示在界面上
/// </summary>
public void PushPanel(UIPanelType panelType)
{
if (panelStack == null)
panelStack = new Stack<BasePanel>();
//判断一下栈里面是否有页面
if (panelStack.Count > 0)
{
BasePanel topPanel = panelStack.Peek();
topPanel.OnPause();
}
BasePanel panel = GetPanel(panelType);
panel.OnEnter();
panelStack.Push(panel);
}
/// <summary>
/// 出栈 ,把页面从界面上移除
/// </summary>
public void PopPanel()
{
if (panelStack == null)
panelStack = new Stack<BasePanel>();
if (panelStack.Count <= 0) return;
//关闭栈顶页面的显示
BasePanel topPanel = panelStack.Pop();
topPanel.OnExit();
if (panelStack.Count <= 0) return;
BasePanel topPanel2 = panelStack.Peek();
topPanel2.OnResume();
}
/// <summary>
/// 根据面板类型 得到实例化的面板
/// </summary>
/// <returns></returns>
private BasePanel GetPanel(UIPanelType panelType)
{
if (panelDict == null)
{
panelDict = new Dictionary<UIPanelType, BasePanel>();
}
//BasePanel panel;
//panelDict.TryGetValue(panelType, out panel);//TODO
BasePanel panel = panelDict.TryGet(panelType);
if (panel == null)
{
//如果找不到,那么就找这个面板的prefab的路径,然后去根据prefab去实例化面板
//string path;
//panelPathDict.TryGetValue(panelType, out path);
string path = panelPathDict.TryGet(panelType);
GameObject instPanel = GameObject.Instantiate(Resources.Load(path)) as GameObject;
instPanel.transform.SetParent(CanvasTransform,false);
panelDict.Add(panelType, instPanel.GetComponent<BasePanel>());
return instPanel.GetComponent<BasePanel>();
}
else
{
return panel;
}
}
[Serializable]
class UIPanelTypeJson
{
public List<UIPanelInfo> infoList;
}
private void ParseUIPanelTypeJson()
{
panelPathDict = new Dictionary<UIPanelType, string>();
TextAsset ta = Resources.Load<TextAsset>("UIPanelType");
UIPanelTypeJson jsonObject = JsonUtility.FromJson<UIPanelTypeJson>(ta.text);
foreach (UIPanelInfo info in jsonObject.infoList)
{
//Debug.Log(info.panelType);
panelPathDict.Add(info.panelType, info.path);
}
}
/// <summary>
/// just for test
/// </summary>
public void Test()
{
string path ;
panelPathDict.TryGetValue(UIPanelType.Knapsack,out path);
Debug.Log(path);
}
}
6测试 新建一个GameRoot脚本挂载在任何物体上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameRoot : MonoBehaviour
{
// Use this for initialization
void Start()
{
UIManager.Instance.Test();
}
// Update is called once per frame
void Update()
{
}
}
7.创建一个BasePanel Panel的公共基类 功能实现如图:
然后 新建一个BasePanel脚本 每个Panel上都要创建一个自己的脚本用来继承自BasePanel,
8,控制UI面板的prefab的实例化创建和 管理! 在UIManager中创建新的一个字典用来存储 Panel的类型和Panel的BasePanel ,再增加一个getPanel 方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class UIManager { // UIManager UI框架的核心管理类 1,解析保存所有面板信息(PanelPathDict)
[Serializable]
class UIPanelTypeJson{
public List<UIPanelInfo> infoList;
}
/// <summary>
/// 单例模式的核心
/// 1定义一个静态的对象 在外界访问 在内结构造
/// 2构造方法私有化
/// </summary>
private static UIManager _instance;
public static UIManager Instance
{
get
{