当前位置:   article > 正文

【Unity】 HTFramework框架(九)UI管理器_ui管理器属于数据还是

ui管理器属于数据还是

更新日期:2019年9月26日。
Github源码:[点我获取源码]
Gitee源码:[点我获取源码]

UI管理器简介

UI管理器用于管理全局的UI实体,以省去手动创建UI实例、销毁UI实例等一系列操作,他可以在非常方便且省去不必要的开销优势下,让你条例清晰的组织和管控好任何复杂的UI结构。

使用UI管理器

UI类型

UI系统有三种类型的UI,分别是Overlay(屏幕空间),Camera(摄像机空间),World(世界空间),每一个UI实体都可以标记其所属的类型,且每一个UI实体的根不需要是一个完整的Canvas,只需要是一个Panel,或者一个Image,甚至一个空的RectTransform就可以。

创建UI实体

创建任意一个UGUI控件,并创建成预制体就可以了,这就是我们的UI实体(如下的GamePanel)。
在这里插入图片描述

创建UI逻辑类

每一个UI实体都由一个UI逻辑类所持有,且只能是一对一的关系,如果你的设计文档中不满足这个要求(比如某个UI逻辑类必须拥有两个UI实体才能实现业务需求),那请你重新设计UI结构(比如尝试着将这两个UI实体合并为一个,或者为另一个多余的实体重新设计一个UI逻辑类)。

新建一个UI逻辑类,必须满足以下条件:
1.继承至UILogicResident或者UILogicTemporary
2.标记特性UIResource

推荐使用快捷创建方式:
Project界面右键 -> Create -> HTFramework -> C# UILogicResident Script
在这里插入图片描述
如下图,我新建了一个名为UILogicGame的逻辑类,他持有的实体为上文创建的GamePanel:

/// <summary>
/// 新建UI逻辑类
/// </summary>
[UIResource("AssetBundleName", "AssetPath", "GamePanel", UIType.Overlay)]
public class UILogicGame : UILogicResident
{
	/// <summary>
	/// 初始化
	/// </summary>
    public override void OnInit()
    {
        base.OnInit();
    }

	/// <summary>
	/// 打开UI
	/// </summary>
    public override void OnOpen(params object[] args)
    {
        base.OnOpen(args);
    }

	/// <summary>
    /// 置顶UI
    /// </summary>
    public override void OnPlaceTop()
    {
        base.OnPlaceTop();
	}
    
	/// <summary>
	/// 关闭UI
	/// </summary>
    public override void OnClose()
    {
        base.OnClose();
    }

	/// <summary>
	/// 销毁UI
	/// </summary>
    public override void OnDestroy()
    {
        base.OnDestroy();
    }

	/// <summary>
	/// UI逻辑刷新
	/// </summary>
    public override void OnUpdate()
    {
        base.OnUpdate();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

UI逻辑类结构

1.UIResource特性标记了此UI逻辑类所指向的UI实体。
第一个参数:AssetBundleName为UI实体所打入的AB包名称;
第二个参数:AssetPath为UI实体在AB包中的路径(必须指明后缀,以便于Editor模式下加载);
第三个参数:ResourcePath为UI实体在Resources中的路径;
第四个参数:UIType为UI实体的类型。
第五个参数:DomainName为世界UI所属的域名。

注意:世界UI可以有多个Canvas根节点,在这里一个Canvas就对应一个域,以string类型的名称区分,每一个世界UI必须属于一个域。

注意:当资源加载方式采用AssetBundle方式时,参数1和参数2有效;当资源加载方式采用Resources方式时,参数3有效。

2.OnInit():UI实体创建成功后呼叫一次,若中途销毁UI,再次创建会重新呼叫。

3.OnOpen(params object[] args):UI打开后呼叫一次。

4.OnPlaceTop():UI置顶后呼叫一次。

5.OnClose():UI关闭后呼叫一次。

6.OnDestroy():UI销毁前呼叫一次。

7.OnUpdate():UI处于打开状态时,每帧呼叫。

注意:UI的逻辑类型分为两类,常驻UI(UILogicResident),非常驻UI(UILogicTemporary),两者之间的主要区别:

1.任何非常驻UI的层级 永远> 任何常驻UI的层级;
(也即是,非常驻UI永远会遮挡常驻UI,所以类似于全屏遮挡的提示、警告之类的可以定义为非常驻UI)

2.常驻UI可以共存,非常驻UI只能同时打开一个;
(也即是,当打开新的非常驻UI,则上一个显示的非常驻UI会自动关闭)

3.只有常驻UI可以被置顶;

打开UI

写好了UI逻辑类,并做好了UI实体,直接调用框架接口就可以打开并显示UI了,不需要手动去管理UI逻辑类和UI实体的创建和销毁过程:

        //打开一个UI
        Main.m_UI.OpenUI<UILogicGame>();
  • 1
  • 2

也可以在协程方法中打开多个UI,并等待这些UI打开完成再进行后续指令:

    private IEnumerator OpenUI()
    {
        //等待打开一个UI
        yield return Main.m_UI.OpenUI<UILogicGame>();
        //等待打开一个UI
        yield return Main.m_UI.OpenUI<UIError>();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

不过,必须在框架UI模块的编辑器面板启用该类型的UI,才能进行正常的打开等操作:
在这里插入图片描述

预加载UI

当然,在首次打开UI时,会经历加载实例和初始化的过程,可能较慢,如果无法等待这点时间,可以提前预加载UI:

        //注意,预加载完成后会呼叫 OnInit 方法

        //预加载一个UI
        Main.m_UI.PreloadingUI<UILogicGame>();
  • 1
  • 2
  • 3
  • 4

关闭UI

被关闭的UI依然存在于内存中,只是不可见了:

        //关闭一个UI
        Main.m_UI.CloseUI<UILogicGame>();
  • 1
  • 2

销毁UI

若这个UI长时间不再使用,需要清理出内存,可以销毁UI:

        //销毁一个UI
        Main.m_UI.DestroyUI<UILogicGame>();
  • 1
  • 2

置顶UI

置顶一个常驻UI:

        //置顶一个处于打开状态的常驻UI
        Main.m_UI.PlaceTop<UILogicGame>();
  • 1
  • 2

获取UI实体(依赖注入)

在UI逻辑类中获取UI实体,只需要调用UIEntity字段就可以了:

	/// <summary>
	/// 初始化
	/// </summary>
    public override void OnInit()
    {
        UIEntity.GetComponentByChild<Text>("Title").text = "Game";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

比如我要获取UI实体下的某一个GameObject,某一个组件,也可以使用InjectPath依赖注入,比如此处我要获取Icon2对象:
在这里插入图片描述
代码中这样写:

public class UIGame : UILogicResident
{
    //参数为路径,比如这里的:Icon1/Icon2
    [InjectPath("Icon1/Icon2")]
    private GameObject _icon2;
    //也可以为组件注入依赖,比如这里的:Transform
    [InjectPath("Icon1/Icon2")]
    private Transform _icon2Tran;

    /// <summary>
    /// 初始化
    /// </summary>
    public override void OnInit()
    {
        base.OnInit();

        //这里_icon2 、_icon2Tran已注入依赖,可以直接使用
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

强制定义UI逻辑与UI实体的对应关系

根据一个UI逻辑类对应一个UI实体的关系,每一个UI逻辑类所持有的UI实体由UIResource特性标记,但在某些时候,对于一些简单的程序,我们既不想使用AB包模式,也不想动态Resources加载,我们就想让某个UI逻辑类使用某个特定的UI实体。
这就需要使用Define UI了,在检视面板可以直接指定某个UI逻辑类使用某个UI实体,该UI实体可以是Scene中的对象,也可以是Project中的预制体。
如下,我强制定义了UILevelPanel界面始终使用Level1作为UI实体,无论他的UIResource标记如何改变。
在这里插入图片描述

数据驱动模式

【Unity】 HTFramework框架(三十九)UI的数据驱动模式。

业务代码拆解

【Unity】 HTFramework框架(五十)【进阶篇】UI界面业务代码拆解,降低强耦合的利器。

运行时检视面板

在编辑器中运行时将会出现运行时检视面板(Runtime Data),主要用以调试或数据监测,目前面板如下:
在这里插入图片描述
1.Overlay UIs:所有的Overlay类型UI,点击OpenClose按钮可以模拟打开或关闭该UI。
2.Camera UIs:所有的Camera类型UI,点击OpenClose按钮可以模拟打开或关闭该UI。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号