基于ET框架和UGUI的简易UI框架(et3.3版)

前言

本框架是在ET框架上进行修改的,使用的是Unity自带的UGUI。

其实ET本身就带有简单的UI框架,建议学习之前先看懂ET里面的UI组件,主要看UIComponent,IUIFactory,UI及与其相关的类,明白ET中整个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:最上层,一般用来做各种遮罩层,屏蔽输入,或者切换动画等

Model层

Model层只有两个脚本:UIPanelConfig.cs和WindowLayer.cs

窗体预制体挂上UIPanelConfig组价,填写对应WindowLayer即可

此处WindowLayer用string常量不用枚举是因为热更需要用到Ilrt,而用枚举需要绑定等问题,所以尽量避免使用枚举,应该改成string或其它值常量

// 层级配置
public class UIPanelConfig : MonoBehaviour
{
    public string WindowLayer = ETModel.WindowLayer.Medium;
}

//窗体层级
public static class WindowLayer
{
    public const string UIHiden = "UIHiden";
    public const string Bottom = "Bottom";
    public const string Medium = "Medium";
    public const string Top = "Top";
    public const string TopMost = "TopMost";
}
image

如感到实在难受或强迫症患者(强迫症使程序更健壮),可以自行写个Editor类,重写OnInspectorGUI()即可实现和枚举一样的效果,在Inspector视图下选择层级,然后对WindowLayer赋值,替代手动打字,不会的可以自行研究和百度。

Hotfix层

热更层只有5个文件,其中只有UIBaseComponent.cs这个是新增的,其余四个均是修改自et源UI框架的。

// UI窗体主控组件需要继承此类
public abstract class UIBaseComponent : Component
{
    public event Action OnCloseOneTime;
    public event Action OnShow;
    public event Action OnClose;

    public bool InShow { get { return Layer != WindowLayer.UIHiden; } }
    public string Layer { get; set; } = WindowLayer.UIHiden;

    public virtual void Show()
    {
        GetParent<UI_Z>().GameObject.SetActive(true);
        OnShow?.Invoke();
    }

    public virtual void Close()
    {
        GetParent<UI_Z>().GameObject.SetActive(false);

        if (OnCloseOneTime != null)
        {
            OnCloseOneTime.Invoke();
            OnCloseOneTime = null;
        }
        OnClose?.Invoke();
    }

    public override void Dispose()
    {
        base.Dispose();

        OnCloseOneTime = null;
        OnShow = null;
        OnClose = null;
        Layer = WindowLayer.UIHiden;
    }
}

所有的窗体主控组件均要继承自此组件,而且每个UI窗体只能存在一个继承自此的组件,用于管理此UI主要行为,如:Show,Close等

PS:OnCloseOneTime和OnClose是因为我项目用到才加的,各位各取所需,不用的可以去掉,或者想要什么功能都可以在这个组件中拓展

注意:在各个窗体的IUIFactory_Z的实现中,Create方法里面,请务必用ui.AddUiComponent();代替原本et中的ui.AddComponent();否则UI_Z中的UiComponent属性会为空

Example

此处放上一个模版,各位可以参考一下,也可以根据项目需要自行修改。

UIXXXComponent和UIXXXFactory大概写法和模版差不多,大家可以自行填充逻辑进去,如果觉得每次手动创建麻烦,也可以自行写个工具,每次创建窗体就自动创建模版,本案例不提供(因为我也懒得做了)

namespace ETHotfix
{
[ObjectSystem]
public class UILoginComponentAwakeSystem : AwakeSystem<UILoginComponent>
{
    public override void Awake(UILoginComponent self)
    {
        self.Awake();
    }
}

public class UILoginComponent : UIBaseComponent//此处继承自UIBaseComponent而不是Component
{
    //Awake方法只调用一次,通常用于获取引用,绑定事件,初始化部分道具
    public void Awake()
    {
        //获取ReferenceCollector的引用
        ReferenceCollector rc = this.GetParent<UI_Z>().GameObject.GetComponent<ReferenceCollector>();

        //通过ReferenceCollector获取添加的物体引用
        //此处获取返回按钮的Button组件,并且绑定点击事件
        rc.GetUnityComponent<Button>("ReturnBtn").Add(OnClickReturnBtn);
    }

    //每次Show窗体都会调用,通常用于初始化界面
    public override void Show()
    {
        base.Show();

        //展示界面逻辑
    }

    //关闭时调用
    public override void Close()
    {
        base.Close();

        //关闭界面逻辑
    }

    //点击返回按钮事件
    private void OnClickReturnBtn()
    {
        //点击退出界面逻辑
    }
}
}

UILoginFactory.cs

namespace ETHotfix
{
[UIFactory(UIType_Z.UILogin)]
public class UILoginFactory : IUIFactory_Z
{
    public UI_Z Create(Scene scene, string type, GameObject parent)
    {
        try
        {
            ResourcesComponent resourcesComponent = Game.Scene.GetComponent<ResourcesComponent>();
            resourcesComponent.LoadBundle($"{type}.unity3d");
            GameObject bundleGameObject = resourcesComponent.GetAsset<GameObject>($"{type}.unity3d", $"{type}");
            GameObject newUi = UnityEngine.Object.Instantiate(bundleGameObject);
            newUi.layer = LayerMask.NameToLayer(LayerNames.UI);
            UI_Z ui = ComponentFactory.Create<UI_Z, GameObject>(newUi);

            //此处务必使用AddUiComponent代替原本et中的AddComponent否则UI_Z中的UiComponent属性会为空
            ui.AddUiComponent<UILoginComponent>();
            return ui;
        }
        catch (Exception e)
        {
            Log.Error(e.ToStr());
            return null;
        }
    }

    public void Remove(string type)
    {
        Game.Scene.GetComponent<ResourcesComponent>().UnloadBundle($"{type}.unity3d");
    }
}
}

下载:

GitHub(国外):

ET模组仓库:https://github.com/egametang/ET-Modules.git

本人工具仓库:https://github.com/HealthyChina/HealthyResource.git

Gitee(国内):

本人工具仓库:https://gitee.com/healthyZ/HealthyResource.git

转载请声明出处和作者(渐渐),你的点赞,分享,转发将是对我最大的鼓励!

码字不易,感谢阅读!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容