wap网站开发和自适应,wordpress商城自动发货,新手学做网站学要做哪些,营销型网站建设目的目录 前言1 UGUI系统原理2 事件系统2.1 EventSystem2.2 InputModules2.3 Raycasters2.4 协作 3 UGUI系统的组件3.1 Image和RawImage3.2 Mask和RectMask2D 扩展UI穿透问题 前言
记录一些最近学到的有关UGUI的知识。
参考 知乎#xff1a;6千字带你入门UGUI源码 书籍#xff… 目录 前言1 UGUI系统原理2 事件系统2.1 EventSystem2.2 InputModules2.3 Raycasters2.4 协作 3 UGUI系统的组件3.1 Image和RawImage3.2 Mask和RectMask2D 扩展UI穿透问题 前言
记录一些最近学到的有关UGUI的知识。
参考 知乎6千字带你入门UGUI源码 书籍《Unity3D高级编程》 1 UGUI系统原理
UGUI是3D网格下建立起来的UI系统它的每个可显示的元素都是通过3D模型网格的形式建立起来的。当UI系统被实例化时UGUI系统首先要做的就是构建网格。
也就是说Unity在制作一个UI元素时都会先构建一个方形网格再将图片放入网格内。可以理解成构建了一个3D模型用一个网格绑定一个材质球材质球内存放要显示的图片。
但这里有个问题就是如果每个元素都生成一个模型且绑定一个材质球存入一张图片那么界面上成千上万的元素就会有成千上万的材质球和图片显然是不可能的因为如果这样的话GPU需要对每个材质球和网格都进行渲染GPU的负担会很重。
UGUI确实对这一部分进行了优化它将一部分相同类型的图片合并成一张图然后将拥有相同图片、相同着色器的材质球指向同一个材质球并且把分散的模型网格合并起来。这样就生成几个大网格、几个不同图集的材质球和几张图集合并这一步是由Canvas实现的。
不过UGUI并不是把所有的网格和材质球合并成一个它只是把相同层级的元素以及相同层级上拥有相同材质球参数的进行合并。合并成一个网格就相当于一个静止的模型如果有任何元素被移动或者销毁或者元素的参数被改变就需要摧毁原来的网格重新进行构建。这样的操作会消耗很多的CPU内存因此我们要想方设法地合并更多元素减少重构次数。这也是UGUI性能优化的一个方向之一。 UI重建rebuild 2 事件系统
UGUI的事件系统由以下三个子版块组成
2.1 EventSystem
事件系统主要是基于输入(键盘、鼠标、触摸或自定义输入)向应用程序中的对象发送事件当然这需要其他组件的配合。当你在GameObject中添加EventSystem时你会发现它并没有太多的功能这是因为EventSystem本身被设计成事件系统不同模块之间通信的管理者和推动者它主要包含以下功能
管理正在使用的输入模块管理哪个游戏对象被选中管理射线检测
管理输入模块InputModule
EventSystem负责管理所有的输入模块InputModule它在Update中调用TickModules更新每一个模块并在满足条件时调用模块的Process方法。
管理选中的游戏对象
当场景中有了新的被选中的对象会通知之前选中的对象执行OnDeselect事件通知新的对象执行OnSelect事件。
管理射线检测
EventSystem中还有一个非常重要的函数RaycastAll()主要是获取目标。这个方法会首先获取所有的BaseRaycast对象调用其Raycast方法然后对最后得到的结果进行排序大部分情况下按深度进行排序也有一些情况下会使用距离、排序顺序SortingOrder如果是UI则根据Canvas面板的Sort order3D物体默认是0或者根据Sorting Layer作为排序依据。
PS在看UGUI性能优化时有一条是将无交互事件的UI的Raycast Target字段设为false我怀疑可能就是为了减少这里的BaseRaycast对象。
2.2 InputModules
输入模块是配置和定制事件系统主逻辑的地方。 自带的输入模块有两个一个是为独立输入(StandaloneInputModule)另一个是为触摸输入(TouchInputModule)。 StandaloneInputModule是PC、MacLinux上的具体实现而TouchInputModule是IOS、Android等移动平台上的具体实现每个模块都按照给定配置接收和分派事件。 运行EventSystem后它会查看附加了哪些输入模块并将事件传递给特定的模块。
而事件执行则通过ExecuteEvent类这个类中定义了许多接口比如鼠标按下、点击、拖拽等。
2.3 Raycasters
Raycasters负责确定目标对象。给定一个屏幕空间位置它们将收集所有潜在目标找出它们是否在给定位置下然后返回离屏幕最近的对象。 系统提供了以下几种类型的Raycaster
Graphic Raycaster 检测UI元素Physics Raycaster 用于3D物理元素Physics 2D Raycaster 用于2D物理元素
2.4 协作
EventSystem会在Update中调用输入模块的Process方法来处理输入消息。PointerInputModule的Process方法会调用EventSystem中的RaycastAll方法进行射线检测。RaycastAll又会调用所有BastRaycaster的Raycast方法执行具体的射线检测操作用以获取屏幕某个点下的所有目标。
获取完点击目标后又会回到PointerInputModule对其触发那些事件接口IPointerClickHandler之类的并传入PointerEventData参数 使用冒泡排序通知直到有能处理对应IEventSystemHandler的UI接收为止比如Button上的Text无点击事件那就父物体Button接收。
举例 当你点击了一个Button组件首先你的行为会在EventSystem的Update中被输入模块的Process方法被抓取到之后输入模块就会调用RaycastAll方法来得到所有屏幕下点击到的目标最后通过冒泡的方式来找到第一个可以接收点击事件的UI目标。确定好UI目标后对其执行点击事件。
3 UGUI系统的组件
3.1 Image和RawImage Unity中的RawImage RawImage从功能上可以看成是丐版的Image。
区别 1.Image只能展示Sprite类型图片RawImage则可以展示各种类型的图片描述为Texture。 2.Sprite 只能用在 Image 组件上做2D and UISprite可以理解为2D特意做的对Texture的封装。 2.Sprite可以做九宫格。 3.Sprite一般用在小图可以打Atlas(图集)。 4.Texture基于纹理寻址模式不能打包Atlas。 5. UI 需要修改UV rect和用到寻址模式的用Texture否则用Sprite。 6. 当图片尺寸很大导致合并图集效率太低也可以用RawImage。
优势 1.Image有Image的优势Image可以九宫格拉伸。 2.RawImage有RawImage的优势RawImage可以UV rect贴图的纹理寻址。 3.一般用Image除了地图寻址滚动之类的从贴图哪个位置开始显示。
3.2 Mask和RectMask2D
它们是遮挡组件可以将子节点下矩形区域外的内容剔除这两个组件的区别主要是剔除方法不同。Mask使用顶点重构的方式剔除矩形区域外的部分而RectMask2D组件则采用着色器的剔除方式。
扩展
UI穿透问题
问题描述在Unity中当UI元素和3D物体同时存在时点击UI可能导致3D物体的点击事件也被触发。
查了一下资料似乎是使用OnMouseDown这个方法导致的网上提到的解决方案是在摄像机上挂载Graphic Raycaster组件然后使用OnPointerClick()方法替代OnMouseDown进行检测。
也有其他解决方案不过也是围绕UI专用的射线检测Graphic Raycaster进行的文章