游戏UI框架——通过Json信息去加载UI面板
发布日期:2021-06-30 19:59:15
浏览次数:3
分类:技术文章
本文共 7734 字,大约阅读时间需要 25 分钟。
这种框架是通过加载编写好的面板Json信息的方式去实现的
例如如下图的游戏主界面中,当点击任务面板时其余的按钮都无法交互,当关闭了任务面板后其余的按钮恢复可交互行为
一:创建预制体
创建所需的所有面板,把他们都拖到Resources文件夹下成为预制体
二:创建存储不同面板信息的Json文件
[ { "panelType": "Main", "panelPath": "Prefabs/UI_Main" }, { "panelType": "Task", "panelPath": "Prefabs/UI_Task" }, { "panelType": "Knapsack", "panelPath": "Prefabs/UI_Knapsack" }, { "panelType": "Battle", "panelPath": "Prefabs/UI_Battle" }, { "panelType": "Skill", "panelPath": "Prefabs/UI_Skill" }, { "panelType": "Shop", "panelPath": "Prefabs/UI_Shop" }, { "panelType": "Setting", "panelPath": "Prefabs/UI_Setting" }, { "panelType": "ItemMessage", "panelPath": "Prefabs/UI_ItemMessage" }]
三:创建面板类型的枚举类
public enum PanelType{ Main, Task, Knapsack, Battle, Skill, Shop, Setting, ItemMessage,}
四:编写UIManager管理类
——解析面板信息的Json文件,将面板类型和面板预制体路径存入一个字典里,字典的键是面板类型,值是面板预制体的路径
解析Json我这里使用了JSONObject插件//存储每个UI信息的字典private Dictionary——创建UIBase脚本,并提供虚方法重写uiInfoDict = new Dictionary ();/// /// 解析Json/// private void ParseJson(){ TextAsset ta = Resources.Load("UIPanelInfo"); JSONObject j = new JSONObject(ta.text); foreach (var temp in j.list) { PanelType panelType = (PanelType)Enum.Parse(typeof(PanelType), temp["panelType"].str); string panelPath = temp["panelPath"].str; uiInfoDict.Add(panelType, panelPath); }}
using UnityEngine;///——得到面板物体上的UIBase组件并存入一个字典里(字典的键是面板类型,值是此面板身上的UIBase)先从存储每个UI的字典uiDict中查找是否有当前类型面板的值,如果没有,则实例化面板并加到uiDict字典中/// 每个UI面板的基类/// public class UIBase : MonoBehaviour{ ////// 面板显示时 /// public virtual void OnView() { } ////// 面板不显示时 /// public virtual void OnDisview() { } ////// 面板停止交互时 /// public virtual void OnPause() { } ////// 面板恢复交互时 /// public virtual void OnResume() { }}
//存储每个UI的字典 private Dictionary——使用栈的数据结构去处理面板的显示首先判断栈中是否存在面板,如果存在面板,则先让栈顶面板禁用交互,然后再得到当前类型的面板入栈并调用面板的显示方法uiDict = new Dictionary (); //存储每个UI信息的字典 private Dictionary uiInfoDict = new Dictionary (); /// /// 得到面板(UIBase) /// /// 面板类型 /// 是否为一级界面 /// 此UI的根位置(在不是一级界面的情况下) ///private UIBase GetPanel(PanelType panelType, bool isLevel1Panel = true, string uiRootPath = "") { UIBase uiPanel; uiDict.TryGetValue(panelType, out uiPanel); if (uiPanel != null) { return uiPanel; } else { string panelPath; uiInfoDict.TryGetValue(panelType, out panelPath); if (panelPath == null) { Debug.LogWarning("此面板类型的路径不存在"); return null; } else { GameObject panel = Resources.Load (panelPath); panel = GameObject.Instantiate(panel); if (isLevel1Panel) { panel.transform.SetParent(UIRoot, false); } else { panel.transform.SetParent(GameObject.Find(uiRootPath).transform, false); } uiDict.Add(panelType, panel.GetComponent ()); return panel.GetComponent (); } } }
///——使用栈的数据结构去处理面板的关闭首先将栈顶面板出栈并调用面板隐藏方法,如果栈中仍存在元素,则让当前栈顶元素启用交互/// 显示面板/// /// 面板类型public void OpenUI(PanelType panelType){ if (panelStack.Count > 0) { UIBase topPanel = panelStack.Peek(); topPanel.OnUnInteractable(); } UIBase uiPanel = GetPanel(panelType); if (uiPanel == null) { return; } uiPanel.OnView(); panelStack.Push(uiPanel);}
///——在不同的面板脚本中重写四种状态/// 关闭面板 /// /// 是否销毁 public void CloseUI(bool destroy = false) { if (panelStack.Count == 0) { return; } UIBase topPanel = panelStack.Pop(); topPanel.OnDisview(); if (destroy) { GameObject.Destroy(topPanel.gameObject } if (panelStack.Count > 0) { panelStack.Peek().OnInteractable(); } }
using UnityEngine;using UnityEngine.UI;public class UI_TaskPanel : UIBase{ public override void OnView() { gameObject.SetActive(true); } public override void OnDisview() { gameObject.SetActive(false); } public override void OnInteractable() { GetComponent().blocksRaycasts = true; } public override void OnUnInteractable() { GetComponent ().blocksRaycasts = false; } public void OnCloseButtonDown() { UIManager.Instance.CloseUI(); }}
——————————UIManage的完整代码
using UnityEngine;using System.Collections.Generic;using System;////// 每个UI面板的基类/// public class UIBase : MonoBehaviour{ ////// 面板显示时 /// public virtual void OnView() { } ////// 面板不显示时 /// public virtual void OnDisview() { } ////// 面板不可交互时 /// public virtual void OnUnInteractable() { } ////// 面板可以交互时 /// public virtual void OnInteractable() { }}public class UIManager{ //单例模式 private static UIManager _instance; public static UIManager Instance { get { if (_instance == null) { _instance = new UIManager(); } return _instance; } } //UI的根位置 private Transform uiRoot; private Transform UIRoot { get { if (uiRoot == null) { uiRoot = GameObject.Find("UICanvas").transform; } return uiRoot; } } //存储每个UI的字典 private DictionaryuiDict = new Dictionary (); //存储每个UI信息的字典 private Dictionary uiInfoDict = new Dictionary (); //存储每个面板的栈 private Stack panelStack = new Stack (); private UIManager() { ParseJson(); } /// /// 显示面板 /// /// 面板类型 public void OpenUI(PanelType panelType) { if (panelStack.Count > 0) { UIBase topPanel = panelStack.Peek(); topPanel.OnUnInteractable(); } UIBase uiPanel = GetPanel(panelType); if (uiPanel == null) { return; } uiPanel.OnView(); panelStack.Push(uiPanel); } ////// 显示面板 /// /// 面板类型 public void OpenUI(PanelType panelType, string uiRootName) { if (panelStack.Count > 0) { UIBase topPanel = panelStack.Peek(); topPanel.OnUnInteractable(); } UIBase uiPanel = GetPanel(panelType, false, uiRootName); if (uiPanel == null) { return; } uiPanel.OnView(); panelStack.Push(uiPanel); } ////// 关闭面板 /// /// 是否销毁 public void CloseUI(bool destroy = false) { if (panelStack.Count == 0) { return; } UIBase topPanel = panelStack.Pop(); topPanel.OnDisview(); if (destroy) { GameObject.Destroy(topPanel.gameObject); } Debug.Log(panelStack.Count); if (panelStack.Count > 0) { panelStack.Peek().OnInteractable(); } } ////// 解析Json /// private void ParseJson() { TextAsset ta = Resources.Load("UIPanelInfo"); JSONObject j = new JSONObject(ta.text); foreach (var temp in j.list) { PanelType panelType = (PanelType)Enum.Parse(typeof(PanelType), temp["panelType"].str); string panelPath = temp["panelPath"].str; uiInfoDict.Add(panelType, panelPath); } } /// /// 得到面板(UIBase) /// /// 面板类型 /// 是否为一级界面 /// 此UI的根位置(在不是一级界面的情况下) ///private UIBase GetPanel(PanelType panelType, bool isLevel1Panel = true, string uiRootName = "") { UIBase uiPanel; uiDict.TryGetValue(panelType, out uiPanel); if (uiPanel != null) { return uiPanel; } else { string panelPath; uiInfoDict.TryGetValue(panelType, out panelPath); if (panelPath == null) { Debug.LogWarning("不存在当前面板类型的预制体"); return null; } else { GameObject panel = Resources.Load (panelPath); panel = GameObject.Instantiate(panel); if (isLevel1Panel) { panel.transform.SetParent(UIRoot, false); } else { panel.transform.SetParent(GameObject.Find(uiRootName).transform, false); } uiDict.Add(panelType, panel.GetComponent ()); return panel.GetComponent (); } } }}
转载地址:https://liuhaowen.blog.csdn.net/article/details/89460570 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2024年04月19日 14时44分53秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
chkconfig使用和级别介绍
2019-04-30
snort 笔记1 ----- 3种模式简介
2019-04-30
ubuntu 快捷键
2019-04-30
linux 根目录下文件夹分析
2019-04-30
ubuntu tar备份
2019-04-30
My notes about backup to ubuntu
2019-04-30
linux 查看分区和文件大小
2019-04-30
IP TCP UDP 结构
2019-04-30
Not using PCAP_FRAMES 解释(snort中)
2019-04-30
数字信号处理——FIR滤波器设计
2019-04-30
技术转管理?这些“坑”你要绕道走
2019-04-30
领域驱动设计(DDD)前夜:面向对象思想
2019-04-30
Ubuntu 14.04 安装TM2009/QQ
2019-04-30
Ubuntu 14.04 安装VMware
2019-04-30
如何解决Linux下USB设备节点名不固定问题
2019-04-30
Camera驱动调试小记
2019-04-30
如何制作Ext4格式镜像文件
2019-04-30
Ubuntu 16.04 安装OpenCV
2019-04-30
Linux下安装EPSON L310打印机驱动
2019-04-30
Androlid MediaPlayer遇到的各种问题
2019-04-30