基于Unity中的NGUI插件,做好通用的UI管理

2015年10月10日 11:24 1 点赞 0 评论 更新于 2025-11-21 19:08

在我的项目经历中,要确保UI管理的通用性,关键在于明确需求是属于框架层面还是项目层面。例如,所有项目都需要一个弹窗提示接口,但不同项目的弹窗样式各异。若在开发时未能想好如何分离这些差异,可将其放入项目类库,以保证框架不受影响,后续再进行重构。

下面针对提问要点,以NGUI框架为基础(UGUI仍在研究中),详细阐述相应方案:

一、UI和场景中物体的交互控制

目前场景中的交互主要有以下几种情况:

  1. 类似血条的显示:可通过摄像机转换坐标的方法,将场景中物体的坐标转换为UI坐标,从而实现血条位置的同步显示。
  2. 对点击等操作的响应:这类操作属于控制管理器的范畴,不应放置在UI框架中。不过,UI框架需要提供UI尺寸与实际尺寸的比例,以便规划控制范围。
  3. 3D物体的展示:3D物体既可以直接放置在界面中,也可以使用renderTexture。直接放置在界面中操作更为方便。

二、切换场景时对UI的处理

虽然Unity为我们提供了Scene功能,但我个人的目标是让整个游戏运行在一个场景中,不过这并不影响UI框架的设计。这里设计了两种管理器,一个是每个场景独有的单例管理器(M2),另一个是跨场景的管理器(M1)。M2负责具体的UI创建和关闭操作,M1则负责对象池等功能。

  • 多场景情况:场景切换时,M2实例和界面会自动销毁,无需特别处理。
  • 单场景情况:UI的创建和销毁由M2实例负责。

三、UI的分组/分类管理

此问题比较模糊,可从资源管理和结构管理两个方面进行分析:

(一)资源管理

  • 小项目:可采用公用图集(+Texture)的方式管理UI资源。
  • 大项目:由于UI资源过多,仅依靠公用图集会导致严重的内存占用。因此,建议采用公用图集 + 功能图集(+Texture)的方式。功能图集是一个功能模块的公用图集,在该功能操作完成后即可释放,以节省内存。这里涉及较多细节,暂不展开。

(二)结构管理

我的思路是将UI分为以下三类:

  1. 控件:包括button、label、sprite等基本元素。像buttonGroup是button的组合,可通过代码进行创建和控制。
  2. 弹窗/界面/列表项:这三者均由控件组合而成。
  3. 共用布局:此类划分旨在节省开发时间。例如,卡牌游戏中反复出现的卡牌布局就是共用布局,若每个界面都重复制作则会造成资源浪费。是否采用共用布局,关键在于UE结构是否明确以及复杂布局的复用程度。

四、统一管理UI的深度

这一问题可引申为对Z坐标(若UI中有3D物体或UI本身为3D形式)、renderQueue、界面调用顺序等全局属性的管理。这些信息应在界面制作时记录在界面信息中,并在创建、聚焦/失焦、关闭界面时同步记录到管理器中。 UI本身的深度管理相对简单,复杂之处在于UI上可能存在3D物体和特效,不同的shader可能会引发不同的问题。

五、打开、关闭及被遮挡时的动效处理

动效更应被视为项目需求而非框架需求。建议设置单独的动效管理器。若项目规划中对动效的规划不明确,可在具体实现中进行处理。 如果项目缺乏靠谱的UE设计,过度完善框架会增加开发负担。引用程序界的质能公式:error=(more code)²。 相较于2D UI,3D UI存在更多问题,需要提前考虑周全。例如,在界面包含3D物体(不使用renderTexture)的情况下打开弹窗时,要处理好Z坐标和缩放的管理。

作者信息

洞悉

洞悉

共发布了 3994 篇文章