前言

此框架对应Et2.0版本,目前已过时!请跳转到最新的et3.3版本:http://www.tinkingli.com/?p=270

本框架是在ET框架上进行修改的,使用的是Unity自带的UGUI。
其实ET本身就带有简单的UI框架,建议学习之前先看懂ET里面的UI组件,主要看UIComponent,IUIFactory,UI及与其相关的类,明白ET中整个UI的运作流程。
其实ET中UI组件一般来说也是够用了,不过我是由原本项目移植到ET框架,我打算部分沿用原框架中的UI架构,再结合ET中的UI组件,就衍生出了这篇文章,一个“基于ET框架和UGUI的简单UI框架”。

框架介绍

本框架特点:

1、层级分明,本框架把UI分成5层,层级依次递增,在Unity面板设置好属性后自动加载到该层

2、关闭界面不直接销毁UI物体,而是调用Close方法,并把界面移到UIHiden层进行隐藏,等待下次Show调用,这样可以避免重复加载和实例化UI物体,当你部分UI界面可能出现多次关闭和打开操作时,能减轻运行压力

3、只需进行一次获取引用操作,一般我们会在Awake中通过ReferenceCollector获取需要引用到的物体(例如:返回按钮,输入文本框等),而Show中负责展示界面逻辑(文本框内容初始化,弹出动画等),因为Awake只会调用一次,而Show则每次打开都会调用,所以能减少GetComponent,以及从ReferenceCollector中取出物体的调用,节省性能的开销

4、拓展方便,假如想要拓展什么想要的功能,大部分都可直接在UIBaseComponent中直接修改即可(下面实例拓展了两个我用到的事件OnCloseOneTime和OnClose,大家用不到可直接去掉)

5、当然也可以手动调用UIComponent.Remove()方法进行真正的移除UI操作(直接销毁物体),有需要的也可以自行实现一个定时卸载操作,就是关闭(Close)一定时间后没有再打开(Show)的UI实行移除(Remove),节约内存

本框架主要是先把所有UI分成5层:
不同层根据名字有不同作用,UIHiden比较特殊,而另外的4层根据名称意思,层级逐层递增
UIHiden:隐藏层,当调用Close的时候,实际上是把UI物体移到该层中进行隐藏
Bottom:底层,一般用来放置最底层的UI
Medium:中间层,比较常用,大部分界面均是放在此层
Top:上层,一般是用来放各种弹窗,小窗口之类的
TopMost:最上层,一般用来做各种遮罩层,屏蔽输入,或者切换动画等

Unity工程中的修改

1.在Model命名空间下添加WindowLayer枚举

namespace Model
{
    //窗体的层级类型
    public enum WindowLayer
    {
        UIHiden = 0, Bottom = 1, Medium = 2, Top = 3, TopMost = 4, } } 

 

2.修改CanvasConfig类,添加UiWindowLayer字段,该字段表明此UI属于哪一层。

public class CanvasConfig: MonoBehaviour
{
	public string CanvasName;
	public WindowLayer UiWindowLayer = WindowLayer.Medium; } 

 

然后直接可以在Unity面板中修改层级

TIM截图20180225093837

UIComponent中的修改(Hotfix工程)

1.添加两个方法,初始化UI层级和修改UI层级

 


//初始化UI层级
private void InstantiateUi(Transform parent)
        { WindowLayer[] _names = new WindowLayer[] { WindowLayer.UIHiden, WindowLayer.Bottom, WindowLayer.Medium, WindowLayer.Top, WindowLayer.TopMost }; Camera _cam = new GameObject().AddComponent<Camera>(); _cam.clearFlags = CameraClearFlags.Depth; _cam.cullingMask = 1 << LayerMask.NameToLayer("UI"); _cam.orthographic = true; _cam.depth = 10; _cam.name = "UiCamera"; _cam.transform.SetParent(parent); _cam.transform.localPosition = Vector3.zero; foreach (var layer in _names) { var it = layer.ToString(); GameObject _go = new GameObject(); this.m_allLayers.Add(layer, _go); Canvas _canvas = _go.AddComponent<Canvas>(); _canvas.renderMode = RenderMode.ScreenSpaceCamera; _canvas.worldCamera = _cam; _canvas.sortingOrder = (int)layer; CanvasScaler _scale = _go.AddComponent<CanvasScaler>(); _scale.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; _scale.referenceResolution = new Vector2(1920, 1080); _scale.matchWidthOrHeight = 1; GraphicRaycaster _graphic = _go.AddComponent<GraphicRaycaster>(); _go.name = it; _go.transform.SetParent(parent); _go.transform.localPosition = Vector3.zero; if (layer == WindowLayer.UIHiden) { _go.layer = LayerMask.NameToLayer("UIHiden"); _graphic.enabled = false; } else { _go.layer = LayerMask.NameToLayer("UI"); } } } //修改UI层级 private void SetViewParent(UI ui, WindowLayer layer) { RectTransform _rt = ui.GameObject.GetComponent<RectTransform>(); _rt.SetParent(m_allLayers[layer].transform); _rt.anchorMin = Vector2.zero; _rt.anchorMax = Vector2.one; _rt.offsetMax = Vector2.zero; _rt.offsetMin = Vector2.zero; _rt.pivot = new Vector2(0.5f, 0.5f)