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框架相关推荐

  1. 【2d游戏开发】unity实现UI框架搭建

    前言 前面一直比较忙,然后到现在才继续接游戏的文章,那么本次将带大家去搭建一个ui框架,同样,需要更具体的教学,可以到b站搜索本人的关于2d游戏开发-unity实现xxx的系列视频. 步骤 其实大致的 ...

  2. Unity | Unity中UI框架的实现与使用

    文章目录 0 前言 1 程序结构 2 工具类:UIPanelInfo.cs 3 PanelType枚举类以及BasePanel类 4 UIManager类 5 UIPanelJson文件 5 使用方法 ...

  3. unity ui框架_[教程汇总+持续更新]Unity从入门到入坟——收藏这一篇就够了

    ----------------塔防(更新中),作者重写了基础篇(下方目录为:1.1(新) 基础)目前还在持续连载了5篇,因为不多我们更新完就能追到原作者的进度了------------------- ...

  4. Unity UI框架的搭建

    为什么要使用UI框架呢? 在我刚使用Unity开发UI界面时,根本没想过用什么UI框架,都是想到要什么界面就通过UGUI拖动什么界面.如果需要实现交互功能,就会绑定对应的监听函数,这样的做法固然是非常 ...

  5. 【Unity自己写框架】FairyGUI UI框架(一)

    笔者之前沉迷游戏无法自拔,但是现在之前玩的游戏也不太爱玩了,发现下班到睡觉之前有2-3个小时空闲,仿佛发现了一笔宝贵的财富不能浪费. 笔者从事手游工作也有两年的时间了,主要做的是逻辑和SDK方面的工作 ...

  6. Unity——基于MVC的UI框架

    Unity--基于MVC的UI框架 前言 今天来学习一下MVC框架思想在Unity项目中的应用 MVC框架 概念 MVC全名是Model View Controller,是模型(Model)-视图(V ...

  7. Unity好的UI框架

    目录 1. 目的 1. 1. 想知道Unity中好的UI框架 2.参考 2.1 基于Unity~UGUI的简单UI框架(附UIFramework源码) 1. 目的 1. 1. 想知道Unity中好的U ...

  8. unity 前端场景搭建UI框架的设计

    在 Unity 前端场景中搭建 UI 框架时,可以采用以下设计方案: 基础组件库:设计一套基础组件库,包括常用的 UI 控件,如文本.按钮.图像等,组件库的设计应该尽量简单易用,方便开发者快速搭建 U ...

  9. Unity手游实战:从0开始SLG——UI框架篇(一)各种UI框架模型简介

    提到游戏的UI开发,几乎没人没听说过MVC吧?MVC最早是为软件架构设计的框架,这里不打算讲MVC的演变过程,需要的了解的可以参考大神的文章,传送门: 你对MVC.MVP.MVVM 三种组合模式分别有 ...

最新文章

  1. 热潮下的冷思考,人工智能即将改变的三大领域
  2. targetNamespace
  3. ELS多种方式集群部署
  4. java调用接口失败重试,httpclient接口测试中重试控制器设置
  5. 一篇漫画,看懂云计算!
  6. CMake 构建项目Android NDK项目基础知识
  7. Lucene 基础理论 (zhuan)
  8. FileOutputSteam入门
  9. PHP在哪里执行_php文件放在哪运行
  10. JavaScript学习笔记:数组
  11. python数据文件输入输出_python 文件输入与输出
  12. php和fastapi,FastAPI快速开始
  13. m3u8播放器-DPlayer,P2P加速 记忆播放
  14. 一步步图解 Java G1 垃圾收集器
  15. VMware虚拟机无法识别U盘解决方案
  16. AOS | 推出无线充电发射器(TX)解决方案
  17. 推荐28个网站,让你边玩边学
  18. 计算机动画制作流程文字版,常见的三维动画制作流程总结
  19. 如何安装Python虚拟环境
  20. APP和网站提示有敏感词怎么办?别慌,一看就会!

热门文章

  1. 七夕来临,程序员该如何花式表白?html+css实现简单七夕表白
  2. 年终奖与年底双薪一样吗?千万别混淆
  3. 计算机软考证书对找工作有帮助吗?
  4. 【Blender】贴图入门教程
  5. scum无法启动此程序以为计算机丢失,人渣SCUM低配电脑画面怎么设置_画面优化设置方法...
  6. maya找回丢失的材质
  7. 闲置交易系统源码二手物品买卖小程序定制
  8. Python实例16:玫瑰花绘制
  9. VS2008环境使用MFC操作读取excel文件
  10. elementUI+vue修改文件名(不是文件夹的话只修改名字,不修改后缀名)的实现方法