【Unity3D-UGUI系列】(一)Canvas 画布组件详解

爱上游戏开发

共 5356字,需浏览 11分钟

 ·

2021-09-01 20:38

作者: 恬静的小魔龙

来源: https://blog.csdn.net/q764424567/article/details/119923544?spm=1001.2014.3001.5501

很早就想分享这个系列的文章,但是总是没有机会,最近就将这个系列整理一下,大家一起学习交流。

一、前言

首先,介绍一个UGUI,NGUI是UGUI的前身,Unity开发团队将NGUI的开发团队收到自己开发团队下,并且由此开发了UGUI。UGUI系统是从Unity 4.6版本后才开始集成到Unity编辑器中。

UGUI的特点:

  • 灵活
  • 快速
  • 可视化

对于开发者来说有很多的优点,比如说:

  • 效率高
  • 实现效果好
  • 易于使用和拓展
  • 与Unity编辑器的兼容性高

这是本系列文章的第一篇:【Unity3D-UGUI系列】(一)Canvas 画布组件详解

二、Canvas 画布介绍

Canvas 画布,所有的UI元素的父物体,其他UI对象想要被渲染就在这个对象的子物体。

当创建一个UI元素的时候,如果没有Canvas 画布,就会自动创建一个画布。

在Unity的Hierarchy面板,选择"Create→UI→Canvas":

三、Canvas画布属性

选中创建的Canvas对象,在Inspect面板上详细了解一下Canvas画布的属性。

Canvas组件自带有三个组件,分别是Canvas、Canvas Scaler、Graphic Raycaster组件,下面就进行分别介绍:

3-1、Canvas:控制UI的渲染模式

Screen Space-Overlay —— 屏幕空间覆盖模式

属性功能
Pixel Perfect使UI元素像素对应,效果就是边缘清晰不模糊
Sort Order多个Canvas时,数值越大越后渲染。值大的 画布,会挡住值小的
Target Display目标显示器,如果有多个屏幕的话可以选择
Addtional Shader Channels附加着色通道,决定Shader可以读取哪些相关数据,比如 法线、 切线 等数据。

这个屏幕空间覆盖模式渲染模式,就是表示不管有没有相机去渲染场景,Canvas下的所有UI永远位于屏幕的前面,覆盖掉渲染场景显示的元素。


Screen Space-Camera —— 相机模式

属性功能
Pixel Perfect使UI元素像素对应,效果就是边缘清晰不模糊
Render Camera渲染的相机
Plane DistanceCanvas与相机之间的距离
Sorting Layer画布的深度,指定了相机的渲染顺序
Order In Layer值越大,该UI越显示在前面

这种渲染模式 适用于场景模型太多太大,在调整UI的时候挡住UI,让UI和渲染的相机移动到比较远的位置,就可以避免遮挡。并且Canvas 和 摄像机之间有一定的距离 , 可以在摄像机和 Canvas之间放置一些模型或粒子特效。


World Space —— 世界模式

属性功能
Event Camera响应事件的相机
Sorting Layer画布的深度,指定了相机的渲染顺序
Order in Layer值越大,该UI越显示在前面
Addtional Shader Channels附加着色通道,决定Shader可以读取哪些相关数据,比如 法线、 切线 等数据。

这种模式下 Canvas 就和场景中哄的其他游戏对象属性一样了,可以控制它的大小、旋转、缩放等。并且UI元素会根据在3D场景歌中的放置位置,来决定渲染在场景其他物体的前面还是后面。这个模式,在我们需要将UI成为我们世界场景的一部分的时候非常有效。

3-2、Canvas Scaler:控制UI画布的放大缩放的比例

Constant Pixer Size —— 恒定像素

属性功能
Scale Factor缩放因子
Reference Pixels Per Uit单位面积像素数量

这种模式下 UI以像素为大小,同样的像素在不同的分辨率下尺寸不一样


Scale With Screen Size —— 屏幕尺寸比例

属性功能
Referencee Resolution预设屏幕大小
Screen Match Mode缩放模式
Match宽高比

这种缩放模式下的UI位置是根据屏幕的分辨率和设置的宽高比来调整UI的位置的,通常做屏幕UI自适应的时候都需要调整到这个缩放模式下。


Constant Physical Size —— 恒定尺寸

属性功能
Physical Unit使用单位
Fallback Screen DPI备用屏幕的DPI
Default Sprite DPI默认图片的DPI
Reference Pixels Per Uit单位面积像素数量

这种模式下 UI以像素为大小,在不同的分辨率下尺寸不一样

3-3、Graphic Raycaster:控制是否让UI响应射线点击

属性功能
Ignore Reversed Graphic忽略反转的UI,UI反转后点击无效。
Blocking Objects阻挡点击物体,当UI前有物体时,点击前面的物体射线会被阻挡。
Blocking Mask阻挡层级,当UI前有设置的层级时,点击前面的物体射线会被阻挡。

四、EventSystem系统详解

Canvas一同创建的还有一个EventSystem,这是一个基于Input的事件系统,可以对键盘、触摸、鼠标、自定义输入进行处理。

4-1、属性面板

Event System(Script)微信搜索公众号 [爱上游戏开发],回复 “资料”,免费领取 200G 学习资料

属性介绍
First Selected首选对象
Send Navigation Events发送导航事件
Drag Threshold拖动阈值

Event System负责处理输入、射线投射以及发送事件。一个场景中只能有一个Event System组件。


Standalone Input Module(Script)

属性介绍
Horizontal Axis横轴
Vertical Axis纵轴
Submit Button提交按钮
Canvel Button取消按钮
Input Actions Per Second每秒输入动作
Repeat Delay重复延迟
Force Module Active力模块激活

Standalone Input Module处理输入的鼠标或触摸事件,进行事件的分发。

4-2、运行流程分析

使用UGUI制作界面时,EventSystem的作用就像是为UGUI设计好的消息中心,它管理着所有能参与消息处理的UGUI组件,比如Panel、Image、Button等。

EventSytem组件,是消息机制的核心。

StandaloneInputModule,是负责产生输入的组件。

StandaloneInputModule继承自BaseInputModule实现类,类似的实现类Unity中还有另外几个,用户也可以自定义一个实现类用于事件处理。

但是,还少一个部分,那就是怎么确定某个事件是发给谁的,EventSystem响应的是用户的点击、触摸、拖动、长按之类的操作,那么EventSystem是怎么确定这些操作是针对谁的呢,所以还需要一个射线检测模块,来判断鼠标对准的UI是哪一个,这也就是GraphicPaycaster组件。

GraphicPaycaster专门负责Canvas下的UI的射线检测和计算问题。

至此,EventSystem在UGUI中的情况就比较清晰了,一个EventSystem对象负责管理所有事件相关对象,该对象下挂载了EventSystem组件和StandaloneInputModule组件,前者为管理脚本,后者为输入模块。Canvas对象下挂载了GraphicRaycaster负责处理射线相关运算,用户的操作都会通过射线检测来映射到UGUI组件上,InputModule将用户的操作转化为射线检测,Raycaster则找到目标对象并通知EventSystem,最后EventSystem发送事件让目标对象进行响应。

整理的流程如下图所示:

4-3、响应接口

UGUI的事件响应处理有多种方式,最简单而直接的一种应该就是通过实现特定接口的方法来处理事件响应了。由于Canvas挂载了GraphicRaycaster组件,因此在Canvas对象之下的所有GUI对象都可以通过挂载脚本并且实现一些和事件相关的接口来处理事件,比如常见的IPointerClickHandler接口就是用于处理点击事件的接口。可以实现的接口列表大概如下所示:

接口说明
IPointerEnterHandler - OnPointerEnter当指针进入对象时调用
IPointerExitHandler - OnPointerExit当指针退出对象时调用
IPointerDownHandler - OnPointerDown当指针压在对象上时调用
IPointerUpHandler - OnPointerUp当指针被释放时调用(在原始按下的对象上调用)
IPointerClickHandler - OnPointerClick当在同一对象上按下和释放指针时调用
IInitializePotentialDragHandler - OnInitializePotentialDrag在找到拖动目标时调用,可用于初始化值
IBeginDragHandler - OnBeginDrag当拖动即将开始时,在拖动对象上调用
IDragHandler - OnDrag当发生拖动时在拖动对象上调用
IEndDragHandler - OnEndDrag当拖动完成时在拖动对象上调用
IDropHandler - OnDrop在拖动完成时对对象调用
IScrollHandler - OnScroll当鼠标滚轮滚动时调用
IUpdateSelectedHandler - OnUpdateSelected在选定的对象上调用
ISelectHandler - OnSelect当对象变成选定对象时调用
IDeselectHandler - OnDeselect被选中的对象被取消选中
IMoveHandler - OnMove当移动事件发生时调用(左、右、上、下等)
ISubmitHandler - OnSubmit在按下提交按钮时调用
ICancelHandler - OnCancel按下取消按钮时调用

只要在挂载的脚本中实现所需要的接口,对应的事件回调也就可以执行了,下面例子演示了如何使用:

public class EventTest : MonoBehaviour, IPointerClickHandler, IDragHandler, IPointerDownHandler, IPointerUpHandler {

    public void OnDrag(PointerEventData eventData) {
        
    }

    public void OnPointerClick(PointerEventData eventData) {
        
    }

    public void OnPointerDown(PointerEventData eventData) {
        
    }

    public void OnPointerUp(PointerEventData eventData) {
        
    }
}


-- END --


公众号后台回复「资料」获取超多学习福利

>>> 点击进入技术讨论群 <<<
▽想深入了解么?

长按/扫码关注我吧↑↑↑


觉得不错就点个在看

浏览 84
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报