UI框架搭建DAY1
分析:UI框架主要是为了用户(使用框架的程序猿)更快捷、方便地开发UI,UI框架的好处还在于解耦,使得程序更具有灵活性。
UI框架的核心是窗口的管理,窗口管理的主要任务就是显示窗口和关闭窗口。
因为窗口的类型多样,比如弹出式窗口,固定位置窗口,隐藏其他窗口(打开这个窗口会覆盖整个屏幕),模态窗口等等。
这里我目前把窗口分为三大类型:普通窗口、弹出式窗口、隐藏其他窗口,而位置固定、是否模态作为窗口的属性。
1.为了更易于复用和拓展,我设计了一个基类BasePanel, NormalPanel, PopupPanel, HiderOtherPanel都由此基类派生。
BasePanel封装了3个重要方法:Open(), Close(), Freeze()。
2.巧妇难为无米之炊,要显示这些窗体首先要制作这些窗体的预制体,然后加载。为此,我又设计了一个核心类PanelManager。
PanelManager主要负责窗体的创建和销毁(隐藏),核心方法CreatePanel()。另外使用了对象池技术,缓存窗体。
3.要动态加载窗体,必须获得窗体资源的路径,为此我设计了一个SysDefine类,此文件用于定义一些预制体路径常量,节点(Inspector面板中的物体位置)常量。(后期重构时打算用Json文件配置)。加载资源的类ResourceManager。
4.此外,我还设计了一个帮助类Helper,目前实现的功能仅仅是自动化设置窗体节点的父节点。
下面,展示我今天下午的成果。
using UnityEngine; public class BasePanel : MonoBehaviour
{
//窗体类型
public EPanelType panelType;
//是否是模态窗口
public bool isModal;
//是否是固定位置窗口
public bool isFixed;
//透明度
ETransparencyLevel transLevel; //初始化
private void Awake()
{
panelType = EPanelType.Normal;
isModal = true;
isFixed = false;
transLevel = ETransparencyLevel.Opaque;
} private void Start()
{
//自动设置物体的父节点
Helper.GetInstance().SetParent(gameObject); } //打开窗口
public void Open()
{
gameObject.SetActive(true);
}
//关闭窗口
public void Close()
{
gameObject.SetActive(false);
}
//冻结窗口
public void Freeze()
{
//TO DO
}
}
using System.Collections.Generic;
using UnityEngine;
public class PanelManager
{
//本类实例
private static PanelManager _instance;
//存储面板名字和对应的路径字典
public static Dictionary<string, string> dictPanelPath;
//存储已显示的面板字典
public static Dictionary<string, BasePanel> dictCurPanel;
//存储已隐藏的面板字典
public static Dictionary<string, BasePanel> dictHidePanel;
//存储Popup类型面板的字典
public static Dictionary<string, Stack<BasePanel>> dictPopupPanel; //单例模式
private PanelManager() { }
public static PanelManager GetInstance()
{
if(_instance == null)
{
_instance = new PanelManager(); InitProperties();
}
return _instance;
}
//初始化字段
private static void InitProperties()
{
dictPanelPath = new Dictionary<string, string>();
dictCurPanel = new Dictionary<string, BasePanel>();
dictHidePanel = new Dictionary<string, BasePanel>();
dictPopupPanel = new Dictionary<string, Stack<BasePanel>>();
}
/// <summary>
/// 创建一个面板
/// 先检查dictHidePanel集合里是否存在此面板,有则取出显示并加入dictCurPanel集合
/// 没有,则创建一个,然后加如dictCurPanel集合。
/// </summary>
/// <param name="panelName">要创建的面板的名字</param>
/// <returns></returns>
public BasePanel CreatePanel(string panelName)
{
BasePanel basePanel = null;
dictHidePanel.TryGetValue(panelName, out basePanel);
if(basePanel != null)
{
return basePanel;
}
else
{
//创建面板
GameObject go = ResourceManager.GetInstance().LoadAsset<GameObject>(panelName);
if(go != null)
{
basePanel = go.GetComponent<BasePanel>();
if(basePanel != null)
{
//添加到正在显示的面板集合
dictCurPanel.Add(panelName, basePanel);
}
else
{
Debug.LogError(GetType()+"你可能忘记挂在了BasePanel类型的脚本");
}
return basePanel;
}
else
{
Debug.Log(GetType()+"panelName可能不存在"); }
}
return null;
} }
using UnityEngine; public class ResourceManager
{
private static ResourceManager _instance;
public static ResourceManager GetInstance()
{
if (_instance == null)
{
_instance = new ResourceManager();
}
return _instance;
}
private ResourceManager() { } public T LoadAsset<T>(string path)where T:Object
{
Object o = Resources.Load(path);
//实例化
GameObject go = GameObject.Instantiate(o) as GameObject; return go as T;
} }
public enum ETransparencyLevel
{
Opaque, //不透明
Translucence, //半透明的
Transparent, //透明的
}
public enum EPanelType
{
Normal,
Popup,
HideOther
}
public class PrefabPathStr
{
public const string uiRootPath = @"Prefabs/UIRoot";
public const string logOnPanelPath = @"Prefabs/LogOnPanel";
}
public class NodePathStr
{
public const string normalPath = @"UIRoot/Normal";
public const string popupPath = @"UIRoot/Popup";
public const string hiderOtherPath = @"UIRoot/HideOther";
} public class SysDefine
{
}
using UnityEngine; public class Helper
{
private static Helper _instance = null; //本类实;
private static Transform normal; //normal 节点
private static Transform popup; //popup 节点
private static Transform hiderOther; //hiderOther 节点 //单利模式
public static Helper GetInstance()
{
if(_instance == null)
{ //本类实例化时,初始化节点字段
normal = GameObject.Find(NodePathStr.normalPath).transform;
popup = GameObject.Find(NodePathStr.popupPath).transform;
hiderOther = GameObject.Find(NodePathStr.hiderOtherPath).transform;
_instance = new Helper();
}
return _instance;
}
private Helper() { }
/// <summary>
/// 若用户自定义了parent则使用,若没有则根据panelType自动设定。
/// </summary>
/// <param name="child">子物体</param>
/// <param name="parent">父物体</param>
public void SetParent(GameObject child, Transform parent = null)
{
if(parent != null)
{
child.transform.SetParent(parent, true);
child.transform.localScale = new Vector3(, , );
child.transform.localPosition = Vector3.zero;
}
else
{
if(child.GetComponent<BasePanel>()!= null)
{
EPanelType panelType = child.GetComponent<BasePanel>().panelType;
switch (panelType)
{
case EPanelType.Normal:
child.transform.SetParent(normal);
break;
case EPanelType.Popup:
child.transform.SetParent(popup);
break;
case EPanelType.HideOther:
child.transform.SetParent(hiderOther);
break;
default:
Debug.LogError("错误,未知的窗体类型");
break;
}
child.transform.localScale = new Vector3(, , );
child.transform.localPosition = Vector3.zero;
}
else
{
Debug.LogError(GetType()+ "请检查此物体是否挂载了BasePanel类型脚本!");
} }
}
}
启动框架类StartGame.cs
using UnityEngine; public class StartGame : MonoBehaviour
{ private GameObject uiRoot = null;
void Start()
{
uiRoot = GameObject.FindGameObjectWithTag("UIRoot");
if (uiRoot != null) //已生成UIRoot
{
Destroy(uiRoot); }
//获取UIRoot对象
uiRoot = ResourceManager.GetInstance().LoadAsset<GameObject>(PrefabPathStr.uiRootPath); //修改克隆体的名字
uiRoot.name = "UIRoot";
//加载场景时不销毁UIRoot
DontDestroyOnLoad(uiRoot); //加载登陆面板
PanelManager.GetInstance().CreatePanel(PrefabPathStr.logOnPanelPath); } }
测试代码LogOnPanel.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class LogOnPanel : BasePanel
{
private void Awake()
{
this.panelType = EPanelType.Normal;
} }
UIRoot预制体效果图
LogOnPanel预制体效果图:
运行效果图:
UI框架搭建DAY1的更多相关文章
- Element UI 框架搭建
Element UI 框架搭建 1.webpack 全局安装 npm install -g webpack 2.淘宝镜像cnpm安装 npm install -g cnpm --registry=ht ...
- UI框架搭建DAY2
今天的主要任务是完善NormalPanel, 搭建PopupPanel. 在编写PanelManager的过程中,发现了一个bug.昨天把panelPath直接传给了ResourceManager.G ...
- ASP.NET MVC搭建项目后台UI框架—1、后台主框架
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—11、自动加载下拉框查询
ASP.NET MVC搭建项目后台UI框架—1.后台主框架 需求:在查询记录的时候,输入第一个字,就自动把以这个字开头的相关记录查找出来,输入2个字就过滤以这两个子开头的记录,依次类推. 突然要用到这 ...
- 从零开始,搭建博客系统MVC5+EF6搭建框架(4)上,前后台页面布局页面实现,介绍使用的UI框架以及JS组件
一.博客系统进度回顾以及页面设计 1.1页面设计说明 紧接前面基础基本完成了框架搭建,现在开始设计页面,前台页面设计我是模仿我博客园的风格来设计的,后台是常规的左右布局风格. 1.2前台页面风格 主页 ...
- ASP.NET MVC搭建项目后台UI框架—2、菜单特效
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—3、面板折叠和展开
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—4、tab多页签支持
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—5、Demo演示Controller和View的交互
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
随机推荐
- python 搭建一个http服务的小例子
一.创建Server 1.Dos 命令 python -m BaseHTTPServer [port] 默认端口是8000, 2.Python 脚本启动 #coding:utf-8 ''' Creat ...
- 项目中phpexcel的基本用法
前提:要下载PHPEXCEL库文件 如:phpexcel官方下载 ,本人使用下载 情形一:对于将数据写入EXCEL表中的用法 header("content-type:text/htm ...
- 使用MegaCli监控Linux硬盘
1.首先查看机器是否使用的是MegaRAID卡 dmesg | grep RAID [ 6.932741] scsi host0: Avago SAS based MegaRAID driver 2. ...
- Maven私服(Repository Manager) - Nexus安装和使用(详细过程)
Maven私服的安装和使用. (注:原创文章,引用请注明来自Clement-Xu的博客!) Maven私服(即Repository Manager)的主要作用: 减少从远方仓库下载的次数,节省带宽.提 ...
- visual studio 2019密钥
企业版:BF8Y8-GN2QH-T84XB-QVY3B-RC4DF 专业版:NYWVH-HT4XC-R2WYW-9Y3CM-X4V3Y
- js返回上一页并刷新、返回上一页、自动刷新页面
一.返回上一页并刷新 <a href="javascript:" onclick="self.location=document.referrer;"&g ...
- puppet(2)-资源介绍
puppet- 资源介绍: 类型.属性与状态同实现方式分离.仅指定目标状态 type {'title': attribute => value, ... } 查看支持的资源类型: puppet ...
- go异常处理原则
如果你定义的函数有可能失败,它就应该返回一个错误.当我调用其他package的函数时,如果这个函数实现的很好,我不需要担心它会panic,除非有真正的异常情况发生,即使那样也不应该是我去处理它.而pa ...
- JDBC driver for MySQL连接提示"The connection property 'zeroDateTimeBehavior' acceptable values are: 'CONVERT_TO_NULL', 'EXCEPTION' or 'ROUND'. The value 'convertToNull' is not acceptable."解决方案
1.使用了8.0以上版本的JDBC driver for MySQL,降回5.x版本. 2.不对JDBC driver for MySQL降级.修改数据库连接字符串,添加serverTimezone属 ...
- java代码理解
public int maxProfit(int k, int[] prices) { int pl = prices.length; int nothin ...