【Framework系列之Client】UIManager和UIPanel模块介绍
今天来介绍一下UIManager和UIPanel模块,话不多说直接开始。
UIManager
功能介绍
UIManager是管理UIPanel的唯一模块,UIManager的主要功能包括:
- 提供打开、隐藏、关闭UIPanel的相关接口。
- 负责UIPanel对象的创建以及初始化。
- 负责储存UIPanel对象实例。
UIManager提供了打开、隐藏、关闭UIPanel的泛型接口,通过传入UIPanel的子类型,就可以对其进行相应的操作。接口代码如下:
/// <summary>打开UI</summary>
/// <typeparam name="T">UI类型</typeparam>
public void OpenUI<T>(Action pCallback = null) where T : Component/// <summary>隐藏UI(不销毁)</summary>
/// <typeparam name="T">UI类型</typeparam>
public void HideUI<T>()/// <summary>关闭UI(销毁)</summary>
/// <typeparam name="T">UI类型</typeparam>
public void CloseUI<T>()
UIManager内以键值对的方式存储UIPanel,当调用OpenUI时会先判断是否存在该UIPanel,如果没有则会加载创建并存储下来。示例代码如下:
public class UIManager : ManagerBase<UIManager>
{private Dictionary<string, GameObject> mUIDictionary = new Dictionary<string, GameObject>();/// <summary>打开UI</summary>/// <typeparam name="T">UI类型</typeparam>public void OpenUI<T>(Action pCallback = null) where T : Component{string uiName = GetUIName<T>();GameObject uiGameObject = null;if (!mUIDictionary.TryGetValue(uiName, out uiGameObject)){uiGameObject = InstantiateUI<T>();if (uiGameObject == null){ManagerCollection.LoadManager.LoadAssetAsync(uiName, (bool pIsSucceeded) =>{OpenUI<T>(pCallback);});}else{uiGameObject.SetActive(true);pCallback?.Invoke();}}else{uiGameObject.SetActive(true);pCallback?.Invoke();}}/// <summary>实例化UI</summary>/// <param name="uiName">面板名称</param>/// <param name="gameObjectAsset">资源</param>/// <returns>面板对象</returns>private GameObject InstantiateUI<T>() where T : Component{GameObject uiGameObject = null;string uiName = GetUIName<T>();GameObject gameObjectAsset = ManagerCollection.ResourceManager.GetGameObject(uiName);if (gameObjectAsset != null){uiGameObject = GameObject.Instantiate(gameObjectAsset);IPanelBase panelBase = uiGameObject.AddComponent<T>() as IPanelBase;panelBase.Init();uiGameObject.transform.SetParent(mCanvasDictionary[panelBase.CanvasType], false);uiGameObject.transform.localScale = Vector3.one;uiGameObject.transform.localRotation = Quaternion.identity;mUIDictionary.Add(uiName, uiGameObject);}return uiGameObject;}
}
设计思路
先说一下UIManager为什么采用泛型接口的设计,而不是通过string作为参数来传递UIPanel的名称。这么做的主要原因是为了正确的获取面板名称。泛型接口通过传递的UIPanel类型来获取名称,这样做的好处在于,在代码编译阶段就可以利用编译器(如VS,VSCode)检测判断类型是否正确,并且可以通过UIPanel类型正确的获取UIPanel的名称。而采用string作为参数传递UIPanel名称,则需要在运行时才能判断UIPanel名称是否正确。所泛型接口能更好的确保代码的正确性。
再说一下InstantiateUI方法中为什么用AddComponent的方式添加UIPanel脚本。原因在于游戏框架被分为Client、Server、Desgin、Resource多个工程,前端和美术在各自的工程项目中开发,流程是美术在Resource工程中制作Prefab资源,制作完成后由程序同步到Client工程中开发脚本逻辑。由于美术在Resource工程中并不会涉及到脚本文件,为了避免不必要的同步,所以在运行时创建UIPanel实例时绑定脚本。
UIPanel模块
功能介绍
UIPanel借鉴了MVC的设计模式,UIPanel分为PanelBase、ControllerBase、ViewBase三个部分,在创建一个新UIPanel时需分别创建三个子类,并继承上面各自的基类。示例代码如下:
/// <summary>UI面板类</summary>
public class UIPanel : PanelBase<UIPanelController, UIPanelView>
{protected override void OnInit(){}
}/// <summary>UI面板Controller类</summary>
public class UIPanelController : ControllerBase<UIPanelView>
{protected override void OnInit(){}
}/// <summary>UI面板View类</summary>
public class UIPanelView : ViewBase<UIController>
{protected override void OnInit(){}
}
Panel部分的主要功能有:
- Panel作为面板的主类,Panel类名作为面板的名称。在UIManager调用泛型接口时,传入Panel类型,如上面代码的UIPanel。
- 负责Controller和View的创建初始化。
Controller部分的主要功能和主要职责有:
- Controller主要负责面板的逻辑部分代码,处理UI响应、事件响应。
- ControllerBase提供了相关UI组件事件响应的接口。
示例代码如下:
protected void RegisterButton(string pGameObjectName, ExButton.EnumCallbackType pCallbackType, Action pCallback)protected void RegisterSlider(string pGameObjectName, ExSlider.EnumCallbackType pCallbackType, Action<float> pCallback)protected void RegisterToggle(string pGameObjectName, ExToggle.EnumCallbackType pCallbackType, Action<bool> pCallback)
View部分的主要功能和职责有:
- View主要负责面板显示部分的代码。
- View储存持有代码中需要用到UI对象。
- View提供获取UI对象和组件的相关接口。
示例代码如下:
public class ViewBase<C> : UIBase, IViewBasewhere C : IControllerBase
{private C mControllerBase;[SerializeField]private List<GameObject> mGameObjectList = new List<GameObject>();public GameObject GetGameObject(string pGameObjectName)public T GetComponent<T>(string pGameObjectName)
}
设计思路
UIPanel借鉴了MVC的设计模式,将UI面板中逻辑处理和界面显示两大部分的代码分开,让代码更加的清晰,从而便于开发与维护。虽然Controller和View可以相互的访问,但在实际开发中还是遵从Controller驱动View的思路来开发。UIPanel先在Controller处理UI响应、事件响应相关逻辑,完成后在View设置相关显示。
相关文档链接
工程源代码:https://gitee.com/huoyixian/release-framework-client
相关文章:
【Framework系列之Client】UIManager和UIPanel模块介绍
今天来介绍一下UIManager和UIPanel模块,话不多说直接开始。 UIManager 功能介绍 UIManager是管理UIPanel的唯一模块,UIManager的主要功能包括: 提供打开、隐藏、关闭UIPanel的相关接口。负责UIPanel对象的创建以及初始化。负责储存UIPanel对…...

阿里云操作系统控制台——ECS操作与性能优化
引言:在数字化时代,云服务器作为强大的计算资源承载平台,为企业和开发者提供了灵活且高效的服务。本文将详细介绍如何一步步操作云服务器 ECS,从开通到组件安装,再到内存全景诊断,帮助快速上手,…...

【长安大学】苹果手机/平板自动连接认证CHD-WIFI脚本(快捷指令)
背景: 已经用这个脚本的记得设置Wifi时候,关闭“自动登录” 前几天实在忍受不了CHD-WIFI动不动就断开,一天要重新连接,点登陆好几次。试了下在网上搜有没有CHD-WIFI的自动连接WIFI自动认证脚本,那样我就可以解放双手&…...

第51天:Web开发-JavaEE应用SpringBoot栈身份验证JWT令牌Security鉴权安全绕过
#知识点 1、安全开发-JavaEE-身份验证-JWT&Security 2、安全开发-JavaEE-安全问题-不安全写法&版本漏洞 #开发框架-SpringBoot 参考:Spring Boot 中文文档 一、身份验证的常见技术: 1、JWT 2、Shiro 3、Spring Security 4、OAuth 2.0 5、SSO 6、…...

中原银行:从“小机+传统数据库”升级为“OceanBase+通用服务器”,30 +系统成功上线|OceanBase DB大咖说(十五)
OceanBase《DB 大咖说》第 15 期,我们邀请到了中原银行金融科技部数据团队负责人,吕春雷。本文为本期大咖说的精选。 吕春雷是一位资历深厚的数据库专家,从传统制造企业、IT企业、甲骨文公司到中原银行,他在数据库技术与运维管理…...
Java面试第八山!《Spring框架》
一、Spring框架概述 Spring是Java企业级应用开发的核心框架,通过控制反转(IoC)和 面向切面编程(AOP)实现模块解耦,简化开发流程。其核心优势包括依赖注入、声明式事务管理、集成主流ORM框架(如…...
LangChain教程 - Agent - 支持 9 种 ReAct 交互
引言 LangChain 总结了 9 种经典的复杂模型交互模式,每种都针对特定任务设计,兼具独特优势与适用场景,内容涵盖: ReAct、Function Call、知识库、搜索等,使用这些模式可以大大简化这些场景开发难度。这些模式可以使用…...

蓝桥杯备赛日记【day1】(c++赛道)
一、裁纸刀问题(2022、规律、思维、省赛) 解法思路: 参考题目给出的例子发现。不管要裁剪多少次。最外围的四次是固定的。然后通过观察发现,我们的行的裁剪次数为(m-1) 次,而每行都需要裁剪列数…...

【大模型基础_毛玉仁】1.4 语言模型的采样方法
【大模型基础_毛玉仁】1.4 语言模型的采样方法 1.4 语言模型的采样方法1.4.1 概率最大化方法1)贪心搜索(GreedySearch)2)波束搜索(BeamSearch) 1.4.2 随机采样方法1)Top-K 采样2)Top…...

[内网安全] Windows 本地认证 — NTLM 哈希和 LM 哈希
关注这个专栏的其他相关笔记:[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01:SAM 文件 & Windows 本地认证流程 0x0101:SAM 文件简介 Windows 本地账户的登录密码是存储在系统本地的 SAM 文件中的,在登录 Windows 的时候&am…...

基于SNR估计的自适应码率LDPC编译码算法matlab性能仿真,对比固定码率LDPC的系统传输性能
目录 1.算法仿真效果 2.算法涉及理论知识概要 2.1 基于序列的SNR估计 2.2 基于SNR估计值进行码率切换 2.3 根据数据量进行码率切换 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下(完整代码运行后无水印)&…...
opencv 模板匹配方法汇总
在OpenCV中,模板匹配是一种在较大图像中查找特定模板图像位置的技术。OpenCV提供了多种模板匹配方法,通过cv2.matchTemplate函数实现,该函数支持的匹配方式主要有以下6种,下面详细介绍每种方法的原理、特点和适用场景。 1. cv2.T…...

Embedding技术:DeepWalkNode2vec
引言 在推荐系统中,Graph Embedding技术已经成为一种强大的工具,用于捕捉用户和物品之间的复杂关系。本文将介绍Graph Embedding的基本概念、原理及其在推荐系统中的应用。 什么是Graph Embedding? Graph Embedding是一种将图中的节点映射…...
微信小程序注册组件
在微信小程序中注册组件分为自定义组件的创建和全局/局部注册,下面为你详细介绍具体步骤和示例。 自定义组件的创建 自定义组件由四个文件组成,分别是 .js(脚本文件)、.json(配置文件)、.wxml(…...

【docker】安装mysql,修改端口号并重启,root改密
我的docker笔记 【centOS】安装docker环境,替换国内镜像 1. 配置镜像源 使用阿里云镜像加速器,编辑/etc/docker/daemon.json sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https:/…...
自定义wordpress三级导航菜单代码
首先,在你的主题functions.php文件中,添加以下代码以注册一个新的菜单位置: function mytheme_register_menus() {register_nav_menus(array(primary-menu > __(Primary Menu, mytheme))); } add_action(init, mytheme_register_menus); …...

洛谷 P1480 A/B Problem(高精度详解)c++
题目链接:P1480 A/B Problem - 洛谷 1.题目分析 1:说明这里是高精度除以低精度的形式,为什么不是高精度除以高精度的形式,是因为它很少见,它的模拟方式是用高精度减法来做的,并不能用小学列竖式的方法模拟…...
JAVA入门——网络编程简介
自己学习时的笔记,可能有点水( 以后可能还会补充(大概率不会) 一、基本概念 网络编程三要素: IP 设备在网络中的唯一标识 端口号 应用软件在设备中的唯一标识两个字节表示的整数,0~1023用于知名的网络…...

Ubuntu 合上屏幕 不待机 设置
有时候需要Ubuntu的机器合上屏幕的时候也能正常工作,而不是处于待机状态。 需要进行配置文件的设置,并重启即可。 1. 修改配置文件 /etc/systemd/logind.conf sudo vi /etc/systemd/logind.conf 然后输入i,进入插入状态,修改如…...

捣鼓180天,我写了一个相册小程序
🙋为什么要做土著相册这样一个产品? ➡️在高压工作之余,我喜欢浏览B站上的熊猫幼崽视频来放松心情。有天在家族群里看到了大嫂分享的侄女卖萌照片,同样感到非常解压。于是开始翻阅过去的聊天记录,却发现部分图片和视…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...

什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...

JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

设计模式-3 行为型模式
一、观察者模式 1、定义 定义对象之间的一对多的依赖关系,这样当一个对象改变状态时,它的所有依赖项都会自动得到通知和更新。 描述复杂的流程控制 描述多个类或者对象之间怎样互相协作共同完成单个对象都无法单独度完成的任务 它涉及算法与对象间职责…...