基于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";
}
基于ET框架和UGUI的简易UI框架(et3.3版)_第1张图片
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().GameObject.SetActive(true);
        OnShow?.Invoke();
    }

    public virtual void Close()
    {
        GetParent().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
{
    public override void Awake(UILoginComponent self)
    {
        self.Awake();
    }
}

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

        //通过ReferenceCollector获取添加的物体引用
        //此处获取返回按钮的Button组件,并且绑定点击事件
        rc.GetUnityComponent

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.LoadBundle($"{type}.unity3d");
            GameObject bundleGameObject = resourcesComponent.GetAsset($"{type}.unity3d", $"{type}");
            GameObject newUi = UnityEngine.Object.Instantiate(bundleGameObject);
            newUi.layer = LayerMask.NameToLayer(LayerNames.UI);
            UI_Z ui = ComponentFactory.Create(newUi);

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

    public void Remove(string type)
    {
        Game.Scene.GetComponent().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

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

码字不易,感谢阅读!

你可能感兴趣的:(基于ET框架和UGUI的简易UI框架(et3.3版))