分析: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的更多相关文章

  1. Element UI 框架搭建

    Element UI 框架搭建 1.webpack 全局安装 npm install -g webpack 2.淘宝镜像cnpm安装 npm install -g cnpm --registry=ht ...

  2. UI框架搭建DAY2

    今天的主要任务是完善NormalPanel, 搭建PopupPanel. 在编写PanelManager的过程中,发现了一个bug.昨天把panelPath直接传给了ResourceManager.G ...

  3. ASP.NET MVC搭建项目后台UI框架—1、后台主框架

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  4. ASP.NET MVC搭建项目后台UI框架—11、自动加载下拉框查询

    ASP.NET MVC搭建项目后台UI框架—1.后台主框架 需求:在查询记录的时候,输入第一个字,就自动把以这个字开头的相关记录查找出来,输入2个字就过滤以这两个子开头的记录,依次类推. 突然要用到这 ...

  5. 从零开始,搭建博客系统MVC5+EF6搭建框架(4)上,前后台页面布局页面实现,介绍使用的UI框架以及JS组件

    一.博客系统进度回顾以及页面设计 1.1页面设计说明 紧接前面基础基本完成了框架搭建,现在开始设计页面,前台页面设计我是模仿我博客园的风格来设计的,后台是常规的左右布局风格. 1.2前台页面风格 主页 ...

  6. ASP.NET MVC搭建项目后台UI框架—2、菜单特效

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  7. ASP.NET MVC搭建项目后台UI框架—3、面板折叠和展开

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  8. ASP.NET MVC搭建项目后台UI框架—4、tab多页签支持

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  9. 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 ...

随机推荐

  1. java改单个插入为批量插入

    单条insert into table value() 13W数据需要执行7小时 变成inert into table value(),(),(),(),() inert into table val ...

  2. python一个简单的websocket测试客户端

    朋友发的,之前在网上一直没找着,先记着 #!/usr/bin/env python import asyncio import websockets import json async def tes ...

  3. linux java 安装

    对于java的开发,有openJDK 和 orcale jdk两种,大多数的linux 系统都会内置openjdk的安装包,但是大多数java项目的开发都是基于orcale jdk的,所以安装orca ...

  4. 【转】app之YdbOnline说明文档

    概述 YdbOnline是面向网页开发者提供的网页开发工具包. 通过使用YdbOnline,网页开发者可借助YdbOnline高效地使用语音.位置等手机系统的能力,同时可以直接使用清除缓存.扫一扫等A ...

  5. mpvue 未找到入口 app.json 文件

    # 1. 先检查下 Node.js 是否安装成功 $ node -v v8.9.0 $ npm -v 5.6.0 到项目的目录 $ npm install $ npm run dev

  6. MySQL 全文检索 ngram插件

    InnoDB全文索引:N-gram Parser[转] MySql5.7 建立全文索引 InnoDB默认的全文索引parser非常合适于Latin,因为Latin是通过空格来分词的.但对于像中文,日文 ...

  7. 更改了react-redux 官方网站的todolist结构

    最近在学习胡子大哈的react小书,内容讲的由浅入深,很值得react,react-redux小白一读. 废话不多说直接上地址:http://huziketang.mangojuice.top/boo ...

  8. 省市区联动,非ajax请求。

    需求 不允许用 ajax 请求的方式加载数据,所以把所有的省市区写在数组里,用js动态加载. 数据源 民政部门户网站:http://www.mca.gov.cn/article/sj/xzqh/201 ...

  9. thinkphp 判断有没有登录 没有登录就自动给他打到登录去

    html 代码 <a href="javascript:;" class="user_uid"> <i class="iconfon ...

  10. Java 递归获取一个路径下的所有文件,文件夹名称

    package com.readfile; import java.io.File; public class GetAllFiles { public static void main(String ...