Unity的UI框架
UI框架
UI框架的含义
含义:UI框架用于管理场景中所有的面板,负责控制面板之间的跳转
UI框架的意义
1、随着游戏系统的复杂化,UI控件越来越多,各个UI之间的直接通讯,已经UI与GameObject之间的关系会越来越复杂
2、代码耦合性会很强
UI框架的实例
1、框架面板的设计
MainMenuPanel:主菜单面板
BagPanel:背包面板
ItemMessagePanel:物品信息面板
ShopPanel:商城面板
SkillPanel:技能面板
SystemPanel:系统面板
TaskPanel:技能面板
我们将设计好的面板做成预制体,放在Resources的目录下。
2、Json数据的读取
UIPanelInfo.json
{"infoList":[{"panelTypeString": "ItemMessage","path": "UIPanel/ItemMessagePanel"},{"panelTypeString": "BagPanel","path": "UIPanel/BagPanel"},{"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"}]
}
将所有信息作为一个infolist类的对象
UIPanelType
public enum UIPanelType
{BagPanel,ItemMessage,MainMenu,Shop,Skill,System,Task,
}
UIManager
public class UIManager
{private Dictionary<UIPanelType, string> panelPathDicr;//存储所有面板Prefab的路径,UIPanelType类型,string用于存储路径private UIManager(){ParseUIPanelTypeJson();//调用ParseUIPanelTypeJson方法解析Json文件}//单例化private static UIManager instance;public static UIManager GetInstance(){if (instance == null){instance = new UIManager();}return instance;}[Serializable]class UIPanelTypeJson//将Json文件视作一个整体,直接将其转换为List<UIPanelInfo>{public List<UIPanelInfo> infoList;}//解析Json文件private void ParseUIPanelTypeJson(){panelPathDicr = new Dictionary<UIPanelType, string>();//生成一个字典TextAsset ta = Resources.Load<TextAsset>("UIPanelType");//加载Json文件中的UIPanelType信息UIPanelTypeJson jsonObject = JsonUtility.FromJson<UIPanelTypeJson>(ta.text);//JsonUtility——工具类,将Json中的文件解析为对象,ta.text就是JSON信息,将JSON信息转换为UIPanelTypeJson类//总的意思就是将JSON文件转换为UIPanelTypeJson类,而UIPanelTypeJson类中则是List<UIPanelInfo>,并其字段infoList对应JSON文件的类名foreach (UIPanelInfo info in jsonObject.infoList)//遍历UIPanelInfo的数组{//Debug.Log(info.panelType);panelPathDicr.Add(info.panelType, info.path);//这里的info相对于生成一个jsonObject.infoList,因此info就是数组中的一个元素。//将对象加入到字典当中去}}public void Test()//测试{string path;panelPathDicr.TryGetValue(UIPanelType.Shop, out path);Debug.Log(path);}
}
UIPanelInfo
[Serializable]
public class UIPanelInfo:ISerializationCallbackReceiver//将UIPanelInfo进行序列化,[Serializable]标签就是运行下面字段可进行读盘和写盘,负责与Json文件向对应,读取Json的文件,传递数据,可以避免直接修改Json文件
{[NonSerialized]public UIPanelType panelType;//记录Json文件中的panelType对象//由于无法直接解析UIPanelType,所有使用string来接受Json数据public string panelTypeString;//{第一种方式转换方式。// get// {// return panelType.ToString();// }// set // {// UIPanelType type = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), value);// panelType = type;// }//}public string path;//记录path的路径字段//反序列化 从文本信息到对象public void OnAfterDeserialize()//每次反序列化后就会调用{UIPanelType type = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);panelType = type;//将文本中的panelTypeString强制转换成UIPanelType}public void OnBeforeSerialize()//每次序列化之前调用这个方法{}
}
分析:
首先
1、UIPanelType类
作为一个枚举类,用于记录各个面板,保存面板的类型
2、UIPanelType.json
这是一个Json文件,用于存储各个面板的具体信息
例如:"panelTypeString": "MainMenu","path": "UIPanel/MainMenuPanel"
panelTypeString保存对象
path保存路径
3、UIPanelInfo
负责与Json文件向对应public UIPanelType panelType;//记录Json文件中的panelType对象public string path;//记录path的路径字段这里要将其设置为可序列化的状态[Serializable],让这个类可以读盘与写盘,方便后期对信息进行修改
,也可以避免直接修改Json文件
4、UIManger
是UI框架的核心,负责管理各种框架
第一步,将其设置为单例模式
第二步,将Json文件解析
第三步,使用UIPanelInfo的数组来接受Json文件的信息
第四步,遍历UIPanelInfo数组,并将其中的数据加入字典当中其中有两个关键点。
第一,加载Json文件,并将文件解析为UIPanelInfo对象的数组
第二,遍历数组,并加入字典中,方便以后对其数据进行各种操作
3、框架逻辑设计
BasePanel的设计
public class BasePanel : MonoBehaviour
{/// <summary>/// 界面被显示出来/// </summary>public virtual void OnEnter(){ }/// <summary>/// 界面暂停/// </summary>public virtual void OnPause(){ }/// <summary>/// 界面继续/// </summary>public virtual void OnResume(){ }/// <summary>/// 界面不显示,退出这个界面,界面被关闭/// </summary>public virtual void OnExit(){ }}
BagPanel继承BasePanel
public class BagPanel:BasePanel
{private CanvasGroup canvasGroup;private void Start(){if (canvasGroup == null){canvasGroup = GetComponent<CanvasGroup>();}}/// <summary>/// 处理页面的关闭/// </summary>public override void OnExit(){// canvasGroup.alpha = 0;canvasGroup.blocksRaycasts = false;transform.DOLocalMoveX(600, 0.5f).OnComplete(() => canvasGroup.alpha = 0);}public void OnClosePanel(){UIManager.GetInstance().PopPanel();}public override void OnEnter(){if (canvasGroup == null){canvasGroup = GetComponent<CanvasGroup>();}canvasGroup.alpha = 1;canvasGroup.blocksRaycasts = true;//弹出动画Vector3 temp = transform.localPosition;temp.x = 600;transform.localPosition = temp;transform.DOLocalMoveX(0, 0.5f);}public override void OnPause(){canvasGroup.blocksRaycasts = false;}public override void OnResume(){canvasGroup.blocksRaycasts = true;}public void OnItemButtonClick(){UIManager.GetInstance().PushPanel(UIPanelType.ItemMessage);}
}
完善后的UIManager
public class UIManager
{private Transform canvasTransform;private Transform CanvasTransform{get {if (canvasTransform == null){canvasTransform = GameObject.Find("Canvas").transform;}return canvasTransform;}}private Dictionary<UIPanelType, string> panelPathDicr;//存储所有面板Prefab的路径,UIPanelType类型,string用于存储路径private Dictionary<UIPanelType, BasePanel> panelDict;//保存所有面板的游戏物体身上的BasePanel组件private Stack<BasePanel> panelStacks;/// <summary>/// 把某个页面入栈,触发相应方法,并显示在界面上/// </summary>public void PushPanel(UIPanelType panelType){if (panelStacks == null){panelStacks = new Stack<BasePanel>();}//判断一下栈里面是否有页面if (panelStacks.Count > 0){BasePanel topPanel = panelStacks.Peek();topPanel.OnPause();}BasePanel panel = GetPanel(panelType);panel.OnEnter();panelStacks.Push(panel);}/// <summary>/// 出栈,把页面从界面上移除/// </summary>public void PopPanel(){if (panelStacks == null){panelStacks = new Stack<BasePanel>();}//BasePanel panel = GetPanel(panelType);if (panelStacks.Count <= 0){return;}BasePanel topPanel = panelStacks.Pop();topPanel.OnExit();if (panelStacks.Count <= 0) return;BasePanel topPanel2 = panelStacks.Peek();topPanel2.OnResume();}/// <summary>/// 根据面板类型,得到实例化的面板/// </summary>/// <returns></returns>public BasePanel GetPanel(UIPanelType panelType){if (panelDict == null){panelDict = new Dictionary<UIPanelType, BasePanel>();}//BasePanel panel;//panelDict.TryGetValue(panelType, out panel);//TODOBasePanel panel = panelDict.TryGet(panelType);if (panel == null){//如果找不到,就找这个面板的Prefab的路径,然后去根据Prefab去实例化面板//string path;//panelPathDicr.TryGetValue(panelType, out path);string path = panelPathDicr.TryGet(panelType);//字典对象的值是已经决定了的,所以不需要使用泛型而dict对象就是panelPathDicr,不需要再赋值字典var pan = Resources.Load(path);GameObject instPanel = GameObject.Instantiate(pan) as GameObject;//实例化instPanel.transform.SetParent(CanvasTransform, false);//TODO false表示局部位置,而非全局位置panelDict.Add(panelType, instPanel.GetComponent<BasePanel>());return instPanel.GetComponent<BasePanel>();}else{return panel;}}private UIManager(){ParseUIPanelTypeJson();//调用ParseUIPanelTypeJson方法解析Json文件}//单例化private static UIManager instance;public static UIManager GetInstance(){if (instance == null){instance = new UIManager();}return instance;}[Serializable]class UIPanelTypeJson//将Json文件视作一个整体,直接将其转换为List<UIPanelInfo>{public List<UIPanelInfo> infoList;}//解析Json文件private void ParseUIPanelTypeJson(){panelPathDicr = new Dictionary<UIPanelType, string>();//生成一个字典TextAsset ta = Resources.Load<TextAsset>("UIPanelType");//加载Json文件中的UIPanelType信息UIPanelTypeJson jsonObject = JsonUtility.FromJson<UIPanelTypeJson>(ta.text);//JsonUtility——工具类,将Json中的文件解析为对象,ta.text就是JSON信息,将JSON信息转换为UIPanelTypeJson类//总的意思就是将JSON文件转换为UIPanelTypeJson类,而UIPanelTypeJson类中则是List<UIPanelInfo>,并其字段infoList对应JSON文件的类名foreach (UIPanelInfo info in jsonObject.infoList)//遍历UIPanelInfo的数组{//Debug.Log(info.panelType);panelPathDicr.Add(info.panelType, info.path);//这里的info相对于生成一个jsonObject.infoList,因此info就是数组中的一个元素。//将对象加入到字典当中去}}public void Test()//测试{string path;panelPathDicr.TryGetValue(UIPanelType.Shop, out path);Debug.Log(path);}
}
分析
1、BasePanel作为基类被其他的具体类继承
而BasePanel中的方法为OnEnter()——进入OnPause()——暂停OnResume()——恢复OnExit()——退出2、具体的类在继承的基础上,进行具体的修改,添加事件3、UIManager则负责使用“栈”来对不同页面进行管理
Unity的UI框架相关推荐
- 【2d游戏开发】unity实现UI框架搭建
前言 前面一直比较忙,然后到现在才继续接游戏的文章,那么本次将带大家去搭建一个ui框架,同样,需要更具体的教学,可以到b站搜索本人的关于2d游戏开发-unity实现xxx的系列视频. 步骤 其实大致的 ...
- Unity | Unity中UI框架的实现与使用
文章目录 0 前言 1 程序结构 2 工具类:UIPanelInfo.cs 3 PanelType枚举类以及BasePanel类 4 UIManager类 5 UIPanelJson文件 5 使用方法 ...
- unity ui框架_[教程汇总+持续更新]Unity从入门到入坟——收藏这一篇就够了
----------------塔防(更新中),作者重写了基础篇(下方目录为:1.1(新) 基础)目前还在持续连载了5篇,因为不多我们更新完就能追到原作者的进度了------------------- ...
- Unity UI框架的搭建
为什么要使用UI框架呢? 在我刚使用Unity开发UI界面时,根本没想过用什么UI框架,都是想到要什么界面就通过UGUI拖动什么界面.如果需要实现交互功能,就会绑定对应的监听函数,这样的做法固然是非常 ...
- 【Unity自己写框架】FairyGUI UI框架(一)
笔者之前沉迷游戏无法自拔,但是现在之前玩的游戏也不太爱玩了,发现下班到睡觉之前有2-3个小时空闲,仿佛发现了一笔宝贵的财富不能浪费. 笔者从事手游工作也有两年的时间了,主要做的是逻辑和SDK方面的工作 ...
- Unity——基于MVC的UI框架
Unity--基于MVC的UI框架 前言 今天来学习一下MVC框架思想在Unity项目中的应用 MVC框架 概念 MVC全名是Model View Controller,是模型(Model)-视图(V ...
- Unity好的UI框架
目录 1. 目的 1. 1. 想知道Unity中好的UI框架 2.参考 2.1 基于Unity~UGUI的简单UI框架(附UIFramework源码) 1. 目的 1. 1. 想知道Unity中好的U ...
- unity 前端场景搭建UI框架的设计
在 Unity 前端场景中搭建 UI 框架时,可以采用以下设计方案: 基础组件库:设计一套基础组件库,包括常用的 UI 控件,如文本.按钮.图像等,组件库的设计应该尽量简单易用,方便开发者快速搭建 U ...
- Unity手游实战:从0开始SLG——UI框架篇(一)各种UI框架模型简介
提到游戏的UI开发,几乎没人没听说过MVC吧?MVC最早是为软件架构设计的框架,这里不打算讲MVC的演变过程,需要的了解的可以参考大神的文章,传送门: 你对MVC.MVP.MVVM 三种组合模式分别有 ...
最新文章
- 热潮下的冷思考,人工智能即将改变的三大领域
- targetNamespace
- ELS多种方式集群部署
- java调用接口失败重试,httpclient接口测试中重试控制器设置
- 一篇漫画,看懂云计算!
- CMake 构建项目Android NDK项目基础知识
- Lucene 基础理论 (zhuan)
- FileOutputSteam入门
- PHP在哪里执行_php文件放在哪运行
- JavaScript学习笔记:数组
- python数据文件输入输出_python 文件输入与输出
- php和fastapi,FastAPI快速开始
- m3u8播放器-DPlayer,P2P加速 记忆播放
- 一步步图解 Java G1 垃圾收集器
- VMware虚拟机无法识别U盘解决方案
- AOS | 推出无线充电发射器(TX)解决方案
- 推荐28个网站,让你边玩边学
- 计算机动画制作流程文字版,常见的三维动画制作流程总结
- 如何安装Python虚拟环境
- APP和网站提示有敏感词怎么办?别慌,一看就会!