Unity UI 框架

这篇具有很好参考价值的文章主要介绍了Unity UI 框架。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

开源地址: 

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

一些相关的思考:

https://blog.csdn.net/NRatel/article/details/127931997https://blog.csdn.net/NRatel/article/details/127931997

一、需求/功能要点

unity ui框架,Unity游戏开发,unity,ui,ugui,ui框架,UI 框架

二、类结构设定

unity ui框架,Unity游戏开发,unity,ui,ugui,ui框架,UI 框架

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

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

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

// 不指定 sortingOrder(使自增)
public T CreatePanel<T>(string panelId, string prefabPath) where T : UIPanel {}

// 以类型名作为id
public T CreatePanel<T>(string prefabPath, int sortingOrder) where T : UIPanel {}

// 以类型名作为id 且 不指定 sortingOrder(使自增)
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, Transform parentTransform, string prefabPath) {}

public T CreateWidget<T>(string widgetId, Transform parentTransform, UIWidgetBehaviour widgetBehaviour) {}

//以类型名作为id
public T CreateWidget<T>(RectTransform parentTransform, string prefabPath) where T : UIWidget {}

//以类型名作为id
public T CreateWidget<T>(Transform parentTransform, UIWidgetBehaviour widgetBehaviour) {}

//不改变自身父物体
public T CreateWidget<T>(string widgetId, UIWidgetBehaviour widgetBehaviour) {}

//以类型名作为id 且 不改变自身父物体
public T CreateWidget<T>(UIWidgetBehaviour widgetBehaviour)

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可深层嵌套,从而适合大规模系统)

unity ui框架,Unity游戏开发,unity,ui,ugui,ui框架,UI 框架

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

额外重要说明:

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

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

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

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

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

unity ui框架,Unity游戏开发,unity,ui,ugui,ui框架,UI 框架

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

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

三、界面配置结构

unity ui框架,Unity游戏开发,unity,ui,ugui,ui框架,UI 框架

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 上,然后从右侧下拉列表中选择想要收集的组件。

 unity ui框架,Unity游戏开发,unity,ui,ugui,ui框架,UI 框架

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

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

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

快捷键更改(2023/10/22):
NRUITools/SetAsUIOpElement (快捷键 alt + 1)
NRUITools/RemoveOpElement (快捷键 alt + 2)

unity ui框架,Unity游戏开发,unity,ui,ugui,ui框架,UI 框架

 ⑶、可点击 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 上进行配置。

unity ui框架,Unity游戏开发,unity,ui,ugui,ui框架,UI 框架

需要注意:框架对 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(支持灵活设置背景、焦点、返回键按下类型,但最好通过增加类型的方式解决)

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

增加1个类型预制(2023年7月6日):

ModalWindow:HasBg = true; BgShowType = HalfAlphaBlack;  BgClickEventType = false; GetFocusType = true;

unity ui框架,Unity游戏开发,unity,ui,ugui,ui框架,UI 框架

 思维导图大图原图

六、Panel 其他配置

1、Panel 厚度配置

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

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

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

对于 “Animator 是否有效” 可以在 UIPanelBehavior 中添加更复杂的检查,比如:
Animator 组件存在、是否启用、是否有Controller资源、内容是否符合要求(有open、close动画,有跳转条件等...)文章来源地址https://www.toymoban.com/news/detail-789114.html

到了这里,关于Unity UI 框架的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【UGUI】学会Unity中UGUI中UI元素自适应问题

    彻底学会Unity中UGUI中UI元素自适应问题 官方介绍:设计用于多种分辨率的 UI - Unity 手册 所所谓自适应就是画面元素跟随屏幕分辨率的改变而保持相对位置或者自身像素同步改变! 屏幕分辨率自适应:依靠画布缩放器组件完成 相对位置:依靠锚点位置完成,锚点主要负责保持

    2024年02月04日
    浏览(37)
  • Unity UGUI事件输入,点击UI无反应

    之前被一个特别低级的UI点击问题卡了好久,记录一下,避免之后再犯同样的错误。 UI事件输入未接受到的原因无非就几个,一一排查总能找到原因。 1、若是直接使用的unity组件中的按钮,但是点击按钮没有反应。         1)查找是否被其他UI遮挡         2)查找是否接收

    2024年04月13日
    浏览(48)
  • 【Unity游戏开发基础】如何做可以调整音量的UI滚动条组件

    游戏的设置列表中,调整游戏声音大小的选项是必备的,如何实现拖动滚动条后音量相应改变大小呢?这里介绍一下相关的脚本和步骤 首先,新建一个调整音量的脚本,名叫SetVolume,把预置的Update方法和Start方法删除。 然后,这个脚本需要挂载在滚动元素的Slider组件下。这个

    2024年02月03日
    浏览(50)
  • Unity3D学习之UI系统——UGUI

    3.2.1 Screen Space -Overlay 覆盖模式 3.2.2 Screen Space - Camera 摄像机模式 创建专门的摄像机渲染UI 并让主摄像机不渲染UI层 3.2.3 World Space 宽高 * 缩放系数 = UI界面大小 参考分辨率 图片格式要改为Sprite 恒定像素模式计算公式 会根据当前分辨率 和 参考分辨率的比率自动计算UI的缩放量

    2024年02月21日
    浏览(260)
  • Unity中UI方案。IMGUI、UIElement、UGUI、NGUI

    引言         unity中有很多ui方案,各种方案有什么优势劣势,这里一一列举一下,知识扩充一下。 UI方案 适用范围 IMGUI 仅用于Editor扩展,或运行时Debug UIElement 可用于发布运行时和Editor UGUI Runtime,两大主流 UI 解决方案之一 NGUI Runtime,两大主流 UI 解决方案之一,现已较少

    2024年02月09日
    浏览(54)
  • Unity UGUI一键绑定UI控件工具(编辑器拓展)

    全为一键生成 实现自动生成代码绑定UI控件 并生成字典保存UI控件 减少自己拖拽 和手动书写过程 适用动态加载面板 建议搭配UI框架使用 根据当前选中的gameobject 查找其下方是否有对应类型的控件 有就保存到字典中 然后通过向上递归拼凑地址,然后生成到粘贴板 直接粘贴到目

    2024年04月23日
    浏览(59)
  • 【unity插件】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件

    一般的shader无法直接使用在UI上,需要在shader中定义特定的面板参数,今天就来推荐github上大佬做的一套开源的一系列UGUI,Shader实现的特效——UIEffect 为 Unity UI 提供视觉效果组件。 https://github.com/Ankh4396/UIEffect 让我们用效果来装饰你的UI!您可以根据需要从脚本和检查器中控

    2024年02月04日
    浏览(43)
  • 【Unity之UI编程】如何用UGUI搭建一个登录注册面板

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : UI_Unity专栏 🅰️ **** 逻辑:没有输入账号密码按下登录的时候打开提示面板,按下确定后返回并移除面板(淡入淡出效果显示) 逻辑:

    2024年01月23日
    浏览(46)
  • 【unity之UI专题】—UI如此简单之UGUI六大组件(GIF思维导图详解)

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : unity常用API 👽 ScreenSpace —overlay(覆盖模式) UI组件一直显示在屏幕前,覆盖所有 对应图示: 👽 ScreenSpace—Camera 摄像机模式 摄像机不

    2023年04月11日
    浏览(58)
  • 【游戏开发小技】Unity通过UI全屏图来模糊场景画面(Shader | 模糊 | 滤镜 | Blur)

    一、前言 嗨,大家好,我是新发。 以前我写文章都是很长很长,接下来我会尝试用新的方式来写博客,尽量简短,以实用为主。同时也是作为自己零碎的一些记录,方便查阅。 本文我要说的是在 Unity 中通过 UI 全屏图来模糊场景画面的效果。 二、效果演示 这是没用模糊效果

    2024年02月05日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包