Unity UI 框架

news2025/1/18 8:46:44

开源地址: 

GitHub - NRatel/NRFramework.UI: 基于 Unity UGUI 的 UI 开发框架基于 Unity UGUI 的 UI 开发框架. Contribute to NRatel/NRFramework.UI development by creating an account on GitHub.https://github.com/NRatel/NRFramework.UI

一、需求/功能要点

二、类结构设定

1、UIPanel 和 UIWidget 继承自 UIView,UIView 聚合 UIWidget。

2、UIRoot 提供 Panel 的创建、关闭、销毁、设置显隐等接口,并对当前层的层级进行管理。

public T CreatePanel<T>(string panelId, string prefabPath, int sortingOrder) where T : UIPanel {}

public T CreatePanel<T>(string panelId, string prefabPath) where T : UIPanel {}

public T CreatePanel<T>(string prefabPath, int sortingOrder) where T : UIPanel {}

public T CreatePanel<T>(string prefabPath) where T : UIPanel {}

public void ClosePanel(string panelId, Action onFinish = null) {}

public void ClosePanel<T>(Action onFinish = null) where T : UIPanel {}

public void DestroyPanel(string panelId) {}

public void DestroyPanel<T>() where T : UIPanel {}

public void SetPanelVisible(string panelId, bool visible) {}

public void SetPanelVisible<T>(bool visible) where T : UIPanel {}

3、UIView 中定义了界面创建基本过程模板,并提供 Widget 的创建、销毁接口。

 public T CreateWidget<T>(string widgetId, RectTransform parentTransform, string prefabPath) where T : UIWidget {}

public T CreateWidget<T>(string widgetId, UIWidgetBehaviour widgetBehaviour) where T : UIWidget {}

public T CreateWidget<T>(RectTransform parentTransform, string prefabPath) where T : UIWidget {}

public T CreateWidget<T>(UIWidgetBehaviour widgetBehaviour) where T : UIWidget {}

public void DestroyWidget(string widgetId) {}

public void DestroyWidget<T>() where T : UIWidget {}

3、UIPanel 中维护自身 显示状态 和 动画状态(重要,管理不好状态,后期可能出现各种异步冲突问题,状态也是系统(如引导)随时操作UI的基础)、并提供操作自身的接口 和 子类可重写的打开/关闭动画接口(比如,播放动画时可将Widget考虑进去)。

public enum UIPanelShowState { Initing, Refreshing, Idle, Hidden, /* Destroyed */ }

public enum UIPanelAnimState { Opening, Idle, Closing, Closed }


protected void CloseSelf(Action onFinish = null) {}

protected void DestroySelf() {}

protected void SetSelfVisible(bool visible) {}


protected virtual void PlayOpenAnim(Action onFinish = null)

protected virtual void PlayCloseAnim(Action onFinish = null)

4、UIManager 中管理整体 Panel,包括背景处理、焦点管理、返回键回退逻辑。提供 创建 UIRoot 、Panel 筛选、组件反射查找(从root开始)等的接口。

public UIRoot CreateRoot(string rootId, int startOrder, int endOrder) {}


public List<UIPanel> FilterPanels(Func<UIPanel, bool> filterFunc = null) {}


public int FindPanelComponent<T>(string rootId, string panelId, string compDefine, out T comp) where T : Component {}

public int FindWidgetComponent<T>(string rootId, string panelId, string[] widgetIds, string compDefine, out T comp) where T : Component {}

public int FindComponentByPath<T>(string path, string compDefine, out T comp) where T : Component {}

(如下图可知,这种结构符合面向对象思想,Widget可深层嵌套,从而适合大规模系统)

---------------------------------------- NRatel 割 ----------------------------------------

额外重要说明:

⑴、所有的 UIPanel 都将创建于同一个 Canvas 下(便于直观了解层级关系)。

⑵、可以按照实际需求创建出若干个UIRoot,独立管理各自层级。

⑶、创建 UIPanel 或 UIWidget 时,可指定 Id,或默认将类型名作为 Id,可指定 Id 的好处是:①,索引更容易;②,相同预设且相同逻辑的界面可重复打开。

⑷、创建 UIPanel 或 UIWidget 时,可通过 prefabPath 创建。需要在 UIView 的 Create 方法中改用自封装的资源加载接口。

⑸、创建 UIWidget 时,允许为一个已存在的 UIWidgetBehaviour 动态绑定逻辑,这意味着支持UI界面预设嵌套,保证了UI预设的复用性。例如(游戏中每个确认框拥有相同的标题栏):

 ⑹、创建 UIPanel 时,可使 SortingOrder 自增(默认),也可直接指定(比如,系统很小,可将所有界面枚举出来,直接配出每个界面的Order)。

⑺、框架不提供 UIPanel 和 UIWidget 的初始化/刷新接口,用户可以自己按需定义。需要注意的是,如果其初始化/刷新 过程是异步的,需要自己维护好显示状态。若是同步的,则不用管(默认是 Idle)。

三、界面配置结构

1、UIView 关联的 UIVeiwBehaviour 继承自 MonoBehaviour,处理元素收集。

2、UIPanel 关联的 UIVeiwBehaviour 继承自 UIVeiwBehaviour,处理 Panel 配置。

3、UIWidget 关联的 UIWidgetBehaviour 继承自 UIVeiwBehaviour,处理 Widget 配置。

四、元素收集与代码生成

1、可同时收集一个 GameObject 上的多个组件。

(经常出现:需要对一个 GameObject 上的多个组件同时操作的情况,如:一个按钮需要操作其显示内容(Image组件)、还要操作其按钮点击事件(Button组件))

2、收集到的元素在 Hierarchy 上显示(方便观察修改)(可配置为关闭)。

3、提供多种操作方式:

⑴、(手动添加)拖拽 Hierarchy上的 GameObject 到 UIPanelBehaviour/UIWidgetBehaviour的 Inspector 上,然后从右侧下拉列表中选择想要收集的组件。

 

 ⑵、(自动推测添加)在 GameObejct 的右键菜单中,

选择 NRUITools/SetAsUIOpElement (快捷键 alt + s)将推测出此GameObejct上一个最可能操作的组件加入操作元素列表。推测优先级为:可交互组件 > 布局相关组件 > 自定义需要添加的组件(可修改) > 图形组件 > RectTransform 或 Transform(保底)

选择 NRUITools/RemoveOpElement (快捷键 alt + r)将移除已收集的此GameObejct上的组件。

 ⑶、可点击 Inspector 上的 “+” 新增、“-” 删除、“清理图标”全部删除、“刷新图标”整理(删除无效的行并合并相同 GameObejct 对应的行)。

4、代码生成

⑴、注意点

①、需要先在 EditorSetting 中设置 uiPrefabRootDir(预设所在根路径)、generatedBaseUIRootDir(基类生成根路径)、generatedTempUIRootDir(快捷业务模板类生成根路径)。

②、路径配置均相对于 Application.dataPath。

③、代码相对于其生成根路径的子路径为:预设相对于uiPrefabRootDir的子路径,若预设不在配置的 uiPrefabRootDir 下,不允许生成。

④、应该在非运行时生成代码(报错检查)。

⑤、生成代码时,将先执行一次整理(删除无效的行并合并相同 GameObejct 对应的行)。

⑵、点击 Inspector 上的 ExportBase 按钮,可生成预设对应的基类。

其中,包含 组件定义、组件可交互事件绑定、组件可交互事件取消绑定、组件定义置null。

组件命名规则为:m_FormatedGoName_CompShortName。

FormatedGoName 将 GoName 去除特殊字符(只保留英文数字下划线),并将其首字母大写。若 FormatedGoName 重复,将在导出时报错提示。

CompShortName 为缩短后的组件名称,可在 UIEditorUtility 的 GetCompShortName 中定义映射关系。

示例如下:


using UnityEngine;
using UnityEngine.UI;
using TMPro;
using NRFramework;

public class UIPanelHomeBase : UIPanel
{
	protected TextMeshProUGUI m_Desc_TMPText;
	protected Image m_Bg_Image;
	protected Button m_BtnAddIcon_Button;
	protected Image m_BtnAddIcon_Image;
	protected RectTransform m_IconRoot_RectTransform;
	protected Button m_BtnTestFindComp_Button;

    protected override void OnBindCompsAndEvents() 
    {
		m_Desc_TMPText = (TextMeshProUGUI)viewBehaviour.GetComponentByIndexs(0, 0);
		m_Bg_Image = (Image)viewBehaviour.GetComponentByIndexs(1, 0);
		m_BtnAddIcon_Button = (Button)viewBehaviour.GetComponentByIndexs(2, 0);
		m_BtnAddIcon_Image = (Image)viewBehaviour.GetComponentByIndexs(2, 1);
		m_IconRoot_RectTransform = (RectTransform)viewBehaviour.GetComponentByIndexs(3, 0);
		m_BtnTestFindComp_Button = (Button)viewBehaviour.GetComponentByIndexs(4, 0);

		BindEvent(m_BtnAddIcon_Button);
		BindEvent(m_BtnTestFindComp_Button);
	}

    protected override void OnUnbindCompsAndEvents() 
    {
		UnbindEvent(m_BtnAddIcon_Button);
		UnbindEvent(m_BtnTestFindComp_Button);

		m_Desc_TMPText = null;
		m_Bg_Image = null;
		m_BtnAddIcon_Button = null;
		m_BtnAddIcon_Image = null;
		m_IconRoot_RectTransform = null;
		m_BtnTestFindComp_Button = null;
	}
}

⑶、点击 Inspector 上的 ExportTemp 按钮,可生成预设对应的快捷业务模板类。

生成的代码文件名及其类名将自动拼上 _Temp,以避免意外覆盖已写代码。

其中主要包含,类的生命周期(若不需要,均可删除)。

示例如下:

using System;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using NRFramework;

public class UIPanelHome_Temp : UIPanelHomeBase
{
    protected override void OnCreating() { }

    protected override void OnCreated() { }

    protected override void OnClicked(Button button) { }

    protected override void OnValueChanged(Toggle toggle, bool value) { }

    protected override void OnValueChanged(Dropdown dropdown, int value) { }

    protected override void OnValueChanged(TMP_Dropdown tmpDropdown, int value) { }

    protected override void OnValueChanged(InputField inputField, string value) { }

    protected override void OnValueChanged(TMP_InputField tmpInputField, string value) { }

    protected override void OnValueChanged(Slider slider, float value) { }

    protected override void OnValueChanged(Scrollbar scrollbar, float value) { }

    protected override void OnValueChanged(ScrollRect scrollRect, Vector2 value) { }
    
    protected override void OnVisibleChanged(bool visible) { }
    
    protected override void OnFocusChanged(bool got) { }

    //protected override void OnBackgroundClicked() { }

    //protected override void OnEscButtonPressed() { }

    protected override void OnDestroying() { }

    protected override void OnDestroyed() { }
}

五、Panel 基本配置分析与设定

从三个“要素” 上分析变量,预定义出五种需求对应的类型。

可在 UIPanelBehaviour 上进行配置。

需要注意:框架对 UIPanel 的处理始终针对 “要素”变量,而非类型。

类型只用作快捷配置出一组自己需要的要素变量。
其中,背景和焦点的配置将随类型完全固定,返回键按下的配置会随类型默认一个最可能的、但是可改(因为其本身的需求可能会比较复杂)。

类型可根据实际需求自行扩展。

-----------------------------------------------------------------

1、三个要素:

⑴、背景:界面打开时自动创建/获取一个全局唯一的RawImage,挂入界面根节点下 FirstSibling。

⑵、焦点:准确地说是“运行焦点”。界面失去焦点时,可选择性地“挂起”(暂停内部耗时Update类操作),并在重新获得焦点时恢复,以此优化。另外,还可在获得焦点时做一些事件触发,比如拍脸弹窗等。

⑶、返回键按下:安卓 Google play 推荐要求处理返回键逻辑,通常需要关闭顶层界面,但有很多例外。

2、五种类型需求(截止目前我用到、想到的):

【铺垫/场景型/全屏界面、一级功能界面等】:有背景(透明、阻挡下方事件、点击背景不响应);获得焦点;返回键按下时可能关闭自身/不响应/自定义

【叠加/局部类型界面(如Home主菜单、较重界面拆分界面等】:无背景;与下方可获得焦点的界面共同获得焦点;返回键按下时不响应/不检测/自定义

【弹出型功能界面、确认框等】:有背景(黑色半透、阻挡下方事件、点击背景默认关闭自身);获得焦点;返回键按下时大概率关闭自身,可能自定义

【浮动功能气泡(如聊天气泡)、Toast等】:无背景、不抢夺焦点;返回键按下时大概率不检测

【网络转圈等待、引导界面等】:有背景(黑色半透、阻挡下方事件、点击背景不响应)、不抢夺焦点;返回键按下时大概率不响应

3、变量定义

HasBg 是否有背景(Bool)

        BgShowType 背景展示类型(Enum)(若有背景)

                Alpha 透明(Color(0, 0, 0, 0))

                HalfAlphaBlack 半透黑色(Color(0, 0, 0, 0.7))

                CustomColor 自定义颜色(Color)

                CustomTexture 自定义贴图(Texture)(不一定需要,暂不实现)

                BlurryScreenshot 模糊屏幕快照(Texture)(不一定需要,暂不实现)

                ?...(可增加预制类型)

        BgClickEventType 背景点击事件类型(Enum)(若有背景)

                PassThrough 不阻挡、穿透

                DontRespone 阻挡但不响应

                CloseSelf 关闭自身

                Custom 触发自定义回调

GetFocusType 获得焦点类型(Bool)

        DontGet 不抢夺焦点

        Get 获得焦点

        GetWithOthers 与下方可获得焦点的界面共同获得焦点

EscPressEventType 返回键按下事件类型(Enum)

        DoneCheck 不检测、跳过

        DontRespone 检测但不响应

        CloseSelf 关闭自身

        Custom 触发自定义回调

4、类型预制 (对应类型需求) (固定背景) (固定焦点) (返回键按下可改)

Underlay(铺垫、全屏的):HasBg = true; BgShowType = Alpha; BgClickEventType = DontRespone; GetFocusType = Get;

Overlay(叠加、局部的):HasBg = false; GetFocusType = GetWithOthers

Window(窗体):HasBg = true; BgShowType = HalfAlphaBlack; BgClickEventType = CloseSelf; GetFocusType = Get

Float(浮动):HasBg = false; GetFocusType = DontGet

System(系统、非业务的):HasBg = true; BgShowType = HalfAlphaBlack;  BgClickEventType = false; GetFocusType = false;

?...(可增加预制类型)

Custom(支持灵活设置背景、焦点、返回键按下类型,但最好通过增加类型的方式解决)

 思维导图大图原图

 

六、Panel 其他配置

1、Panel 厚度配置

框架将为每个 Panel 自动添加一个Canvas,以供排序、避免所有UI在同一个Canvas下重建耗时、添加3D特效等。排序时默认每个Panel 的厚度为 10,若不够,可以自行修改。

2、Panel 打开/关闭动画配置

当 UIPanelBehavior 统计物体上存在有效的 Animator 组件组件时,打开/关闭动画的配置将被激活,此时,可以设定 Panel 在打开/关闭时 AutoPlay(自动播放动画) 或 ControlBySelf(由自己在代码中控制播放)。

对于 “Animator 是否有效” 可以在 UIPanelBehavior 中添加更复杂的检查,比如:
Animator 组件存在、是否启用、是否有Controller资源、内容是否符合要求(有open、close动画,有跳转条件等...)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/18666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

headscale的部署方法和使用教程

headscale的部署方法和使用教程1. headscale文件下载2. 上传并赋予文件权限3. 创建以及修改相关配置文件3.1 创建配置目录&#xff1a;3.2 创建目录用来存储数据与证书&#xff1a;3.3 创建空的 SQLite 数据库文件&#xff1a;3.4 创建 Headscale 配置文件&#xff1a;3.5 创建…

Vue 组件间通信并不是每一次操作都会触发新的通信

需求&#xff1a;新增或者修改都需要组件间立马通信。 操作&#xff1a;把B组件(子组件&#xff0c;这里指的是三级联动组件)的数据传输过来&#xff0c;在A(父组件)组件中处理 即 子传父 这里指的是修改页面或者新增页面三级联动下拉选择完之后 点击 提交 会执行A组件的修改操…

开启安全测试评估赛道,永信至诚发布“数字风洞”产品体系

11月19日&#xff0c;永信至诚产品战略发布会上&#xff0c;面向安全测试评估领域的“数字风洞”产品体系战略发布&#xff0c;标志着永信至诚作为网络靶场和人才建设领军企业&#xff0c;再次以“产品乘服务”的价值体系&#xff0c;开启网络安全测试评估专业赛道。 数字化时代…

MySQL安装

本笔记来自B站黑马程序员讲解的MySQL的使用。 目录 ​编辑 一、MySQL的安装 1、数据库基础概念 2、MySQL下载并安装​编辑 三、启动MySQL 四、连接MySQL数据库 1、使用MySQL提供的客户端命令来连接 2、使用Windows 命令打开&#xff1a; 第一步 配置path的环境变量 第…

uniapp入门:常用事件绑定与数据同步

1.常见事件与事件绑定 1.1点击事件bindtap 1.2 文本输入事件bindinput 1.3 切换事件bindtouchend 2.数据同步 2.1事件回调 2.2逻辑层中page对象中的中数据如何进行改变 2.3页面触发事件如何传参到page中数据 …

ASEMI代理艾赛斯二极管DSA300I100NA,肖特基DSA300I100NA

编辑-Z 艾赛斯硅肖特基二极管DSA300I100NA参数&#xff1a; 型号&#xff1a;DSA300I100NA 最大重复反向阻断电压&#xff08;VRRM&#xff09;&#xff1a;100V 反向电流、漏极电流&#xff08;IR&#xff09;&#xff1a;3mA 正向电压降&#xff08;VF&#xff09;&…

STM32CubeMX外部中断

建议提前学习&#xff1a;使用STM32CubeMX实现按下按键&#xff0c;电平反转&#xff1b; 目录 EXTI 中断 中断的概念 抢占优先级与响应优先级 中断分组 事件 上升沿&#xff0c;下降沿以及双边沿触发 上升沿&#xff0c;下降沿以及双边沿的概念 上升沿&#xff0c;下…

数据结构-双链表思路解析及代码实现

双链表是单链表的进阶版&#xff0c;单链表是1-2-3-4 一个个排排坐链接&#xff0c;只管向后拉手&#xff0c;其主要思想是当前节点与下一节点的关系&#xff0c;那么双链表就多了一层关系&#xff0c;当前节点不仅和一下一点连起来&#xff0c;也要和上一节点串联起来。与前与…

【全志T113-S3_100ask】13-1 Linux c语言ioctl驱动oled(iic、ssd1306)屏幕

【全志T113-S3_100ask】13-1 Linux C通过ioctl驱动oled[ssd1306]屏幕 背景&#xff08;一&#xff09;i2c关键结构体1、i2c_rdwr_ioctl_data结构体2、struct i2c_msg结构体&#xff08;二&#xff09;i2c关键代码1、写函数2、读函数&#xff08;三&#xff09;对oled的操作&…

深度学习和神经网络的介绍(一)

1、深度学习和神经网络 1.1 深度学习的介绍 目标&#xff1a; 知道什么是深度学习知道深度学习和机器学习的区别能够说出深度学习的主要应用场景知道深度学习的常见框架 1.1.1 深度学习的概念 深度学习是机器学习的分支&#xff0c;是一种以人工神经网络为架构&#xff0c…

计算机网络4小时速成:计算机网络基础,计网组成,计网分类,性能指标,标准化组织,计网结构模型,五层模型

计算机网络4小时速成&#xff1a;计算机网络基础&#xff0c;计网组成&#xff0c;计网分类&#xff0c;性能指标&#xff0c;标准化组织&#xff0c;计网结构模型&#xff0c;五层模型 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&…

05_TCP并发服务器

知识点1【TCP并发服务器】 1、多线程&#xff08;常用&#xff09; 2、解决上述问题&#xff1a;端口复用 仅仅是端口的复用 3、并发服务器 多进程实现 总结&#xff1a; 知识点2【HTTP协议】 HTTP基于TCP 1、HTTP协议的概述 2、Webserver 通信过程 3、Web编程开发 知识…

Cadence orcad 批量设置原理图标题栏

前言 作为一份规范的原理图文件&#xff0c;必须要有Title Block&#xff0c;一般是在右下角的原理图信息&#xff0c;包括标题&#xff0c;图纸尺寸&#xff0c;设计师&#xff0c;时间&#xff0c;页码等等。 这里需要两个操作&#xff1a; 一、批量修改Title Block的信息 …

Go语言进阶篇,单元测试、基准测试的性能测试、内存占用测试

在go语言中的单元测试比较有意思&#xff0c;比如测试一个函数是很方便的&#xff0c;只需要将文件名修改为_test.go这样的后缀即可&#xff0c;我们新建一个目录xxx&#xff0c;然后新建xxx_test.go文件&#xff0c;当然这个xxx的名字你可以按照功能来命名&#xff0c;如下&am…

Java开发:多线程编程

本章篇幅主要记录多线程编程相关的知识&#xff0c;如有纰漏&#xff0c;望指出。 话不多说&#xff0c;正式开启多线程之旅... 目录 一、多线程使用方式 A、Thread B、Runnable&#xff08;推荐&#xff09; C、Callable 二、线程的五个状态 三、线程停止 四、线程休…

LabVIEW性能和内存管理 7 LabVIEW中局部和全局变量的内存分配

LabVIEW性能和内存管理 7 LabVIEW中局部和全局变量的内存分配 本文介绍LabVIEW性能和内存管理的几个建议7。 LabVIEW Cleanup – LabVIEW cleans upmany references when the owning VI goes idle and others when the process closes – Manually closereferences t…

Bean的作用域和生命周期

1. Bean 的作用域 对于全局变量,局部变量等的作用域相信大家都已经很清楚了,但是对于对象作用域有点摸不着头脑,下面通过一个简单的案例,康康对象的作用域 1.1 案例引入 现有一个公共的 Bean 对象 package com.bean.model;import org.springframework.stereotype.Componen…

【IEEE2017】RL:机器人库:一种面向对象的机器人应用程序的方法

RL&#xff1a;机器人库&#xff1a;一种面向对象的机器人应用程序的方法 摘要&#xff1a; 摘要&#xff1a;我们讨论了机器人库&#xff08;RL&#xff09;的架构和软件工程原理。在机器人系统、研究项目、工业应用和教育的需求的驱动下&#xff0c;我们确定了相关的设计需求…

linux上如何搭建Java环境

一 linux软件安装常用的方式对比 Linux下的软件安装&#xff0c;主要有如下三种&#xff0c;“正规”程度依次递减&#xff1a; 1、使用标准的yum/apt/yast包管理程序安装 2、使用标准rpm/deb或厂商自己的安装包&#xff08;比如nVidia的显卡驱动用的bin包&#xff09;安装 …

黑*头条_第2章_文章列表前端成形与后端变身

黑*头条_第2章_文章列表前端成形与后端变身 文章目录黑*头条_第2章_文章列表前端成形与后端变身文章列表前端成形与后端变身学习目标1.前端工程结构1.1 环境准备1.1.1 导入工程1.1.2 测试运行1.2 weex 跨终端前端框架1.3 工程结构说明1.4 源码结构1.5 WEEX UI2.文章列表前端开发…