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 ...
随机推荐
- 火币网行情获取的websocket客户端
从验证结果看应该是网络关闭了,不过程序写的不错,可以作为其它websocket客户端的测试程序 # !/usr/bin/env python # -*- coding: utf-8 -*- # aut ...
- 乾坤合一~Linux设备驱动之USB主机和设备驱动
如果不能陪你到最后 是否后悔当初我们牵手 如果当初没能遇见你 现在的我 在哪里逗留 所有的爱都是冒险 那就心甘情愿 等待我们一生中 所有悬念 我一往情深的恋人 她是我的爱人 她给我的爱就像是 带着露水 ...
- 使用redis原生list结构作为消息队列取代celery框架。
1.web后台对大批量的繁重的io任务需要解耦使用分布式异步技术,否则会使接口阻塞,并发延迟,一般就选celery好了.此篇的取代主要是针对取代celery的worker模式.没有涉及到周期和定时模式 ...
- 如何在Linux下修改Mysql的用户(root)密码
下面给大家分享下在Linux下如何修改Mysql的用户(root)的密码,分两种情况:第一种当拥有原来的mysql的root密码,第二种情况忘记原来的mysql的root的密码. 修改的用户都以roo ...
- VS2017 编译Assimp
1. 下载Assimp:http://assimp.sourceforge.net/ 2. 要下载和安装DirectX SDK 安装出现错误,错误代码s1023,解决方法:https://blog.c ...
- win10下VS2017配置GSL库
GSL库:GNU Scientific Library 1. 下载:下载Complete package, except sources和Sources两个exe文件 2. 安装:将两个exe安装 ...
- 【HTML5】video 标签禁用自带的下载按钮
h5自带的 video标签 ,会有个下载按钮,有时候想避免,就可以利用样式的方法 <style type="text/css"> video::-internal-me ...
- 【Static Program Analysis - Chapter 2】 代码的表征之控制流图
(a) an if-then-else (b) a while loop (c) a natural loop with two exits, e.g. while with an if...br ...
- vue项目实战中的增、删、改、查
参考:https://blog.csdn.net/xr510002594/article/details/81665762?utm_source=blogxgwz0 https://blog.csdn ...
- 在微信下载app引导页代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...