目录
UGUI基础
六大组件
Canvas对象上依附的:
- Canvas:画布组件,主要用于渲染 UI 控件
- Canvas Scaler:画布分辨率自适应组件,主要用于分辨率自适应
- Graphic Raycaster:射线事件交互组件,主要用于控制射线响应相关
- RectTransform:Ul 对象位置锚点控制组件,主要用于控制位置和对其方式
EventSystem对象上依附的: - EventSystem和Standalone Input Module玩家输入事件响应系统和独立输入模块组件,主要用于监听玩家操作
Canvas 的三种渲染方式 Render Mode
Screen Space -Overlay:屏幕空间,覆盖模式,UI始终在前
Screen Space -Camera:屏幕空间,摄像机模式,3D物体可以显示在UI之前
World Space:世界空间,3D模式
Screen Space -Overlay
Pixel Perfect:是否开启无锯齿精确渲染(性能换效果)
SortOrder:排序层编号(用于控制多个Canvas时的渲染先后顺序)
TargetDisplay:目标设备(在哪个显示设备上显示)
Additional Shader Channels:其他着色器通道,决定着色器可以读取哪些数据
Screen Space -Camera:
RenderCamera :用于渲染UI的摄像机 (如果不设置将类似于覆盖模式)
Plane Distance: UI平面在摄像机前方的距离,类似整体Z轴的感觉
Sorting Layer:所在排序层
Order in Layer: 排序层的序号
World Space
3D模式,可以把UI对象像3D物体一样处理,常用于VR或者AR
Event Camera:用于处理UI事件的摄像机(如果不设置,不能正常注册UI事件)
CanvasScaler 是什么
CanvasScaler意思是画布缩放控制器,它是用于分辨率自适应的组件
它主要负责在不同分辨率下UI控件大小自适应它并不负责位置,位置由之后的RectTransform组件负责
它主要提供了三种用于分辨率自适应的模式,我们可以选择符合我们项目需求的方式进行分辨率自适应
屏幕分辨率
宽高 * 缩放系数 = 屏幕分辨率
小结
屏幕分辨率——当前设备的分辨率,编辑器下Game窗口中可以查看到
参考分辨率——在其中一种适配模式中出现的关键参数,参与分辨率自适应的计算
画布宽高和缩放系数——分辨率自适应会改变的参数,通过屏幕分辨率和参考分辨率计算而来
分辨率大小自适应——通过一定的算法以屏幕分辨率和参考分辨率参与计算得出缩放系数该结果会影响所有U控件的缩放大小
CanvasScaler的三种适配模式
Constant Pixel Size(恒定像素模式):无论屏幕大小如何,U始终保持相同像素大小
Scale With Screen Size(缩放模式):根据屏幕尺寸进行缩放,随着屏幕尺寸放大缩小
Constant Physical Size(恒定物理模式):无论屏幕大小和分辨率如何,UI元素始终保持相同物理大小
Constant Pixel Size(恒定像素模式)
Scale Factor:缩放系数,按此系数缩放画布中的所有UI元素
Reference Pixels Per Unit:单位参考像素,多少像素对应Unity中的一个单位(默认一个单位为100像素图片设置中的Pixels Per Unit设置,会和该参数一起参与计算
恒定像素模式计算公式:
UI原始尺寸 = 图片大小(像素) / (Pixels Per Unit / Reference Pixels Per Unit)
总结
恒定像素模式,它不会让UI控件进行分辨率大小自适应,会让UI控件始终保持设置的尺寸大小显示,
一般在进行游戏开发极少使用这种模式,除非通过代码计算来设置缩放系数
CanvasScaler(缩放模式)
Reference Resolution:参考分辨率(美术同学出图的标准分辨率)
缩放模式下的所有匹配模式都会基于参考分辨率进行自适应计算
Screen Match Mode:屏幕匹配模式,当前屏幕分辨率宽高比不适应参考分辨率时,用于分
辨率大小自适应的匹配模式
缩放模式中的三种匹配方式
Expand:水平或垂直拓展画布区域,会根据宽高比的变化来放大缩小画布,可能有黑边
Shrink:水平或垂直裁剪画布区域,会根据宽高比的变化来放大缩小画布,可能会裁剪
Match Width Or Height:以宽高或者二者的平均值作为参考来缩放画布区域
Expand
拓展匹配
将Canvas Size进行宽或高扩大,让他高于参考分辨率
计算公式:
缩放系数 = Mathf.Min(屏幕宽/参考分辨率宽,屏幕高/参考分辨率高);
画布尺寸=屏幕尺寸/缩放系数
表现效果:最大程度的缩小UI元素,保留UI控件所有细节,可能会留黑边
例:
将Canvas Size进行宽或高扩大,让他高于参考分辨率
计算公式:
缩放系数= Mathf.Min(800/1920,600/1080)=MathfMin(0.41667,0.5555) ≈ 0.41667
画布尺寸 =(800,600)/0.41667 ≈ (1920,1440)
Shrink
收缩模式
将Canvas Size进行宽或高收缩,让他低于参考分辨率
计算公式
缩放系数 = Mathf.Max(屏幕宽/参考分辨率宽,屏幕高/参考分辨率高)
画布尺寸= 屏幕尺寸/缩放系数
表现效果:最大程度的放大UI元素,让UI元素能够填满画面,可能会出现裁剪
例:
将Canvas Size进行宽或高收缩,让他低于参考分辨率
计算公式:
缩放系数= Mathf.Max(800/1920,600/1080)= Mathf.Max(0.41667,0.5555 )≈ 0.5555
画布尺寸 =(800,600)/0.5555 ≈ (1440,1080)
Match Width Or Height
宽高匹配
以宽高或者二者的某种平均值作为参考来缩放画布
Match:确定用于计算的宽高匹配值
计算公式描述
//在取平均值之前,我们先取相对宽度和高度的对数
float logWidth = Mathf.Log(屏幕宽/参考分辨率宽,2);
float logHeight = Mathf.Log(屏幕高/参考分辨率高,2);
//在对数空间中变换是为了获得更好的性能以及更准确的结果
float logWeightedAverage = MathfLerp(logWidth, logHeight, m MatchWidthOrHeight);
scaleFactor = Mathf.Pow(2, logWeightedAverage);
主要掌握
表现效果
主要用于只有横屏模式或者竖屏模式的游戏
竖屏游戏:Match=0
将画布宽度设置为参考分辨率的宽度并保持比例不变,屏幕越高可能会有黑边
横屏游戏:Match=1
将画布高度设置为参考分辨率的高度并保持比例不变,屏幕越长可能会有黑边
总结
游戏开发一般使用Scale With Screen Size 缩放模式
使用建议
存在横竖屏切换选择:
Expand(拓展匹配,有黑边)和Shrink(收缩匹配,有裁剪
不存在横竖屏切换(定死的横屏或者竖屏游戏):
Match Width or Height(宽高匹配)
横屏游戏 Match= 1
竖屏游戏 Match=0
Constant Physical Size(恒定物理模式)
无论屏幕大小和分辨率如何,U元素始终保持相同物理大小。
DPI:(Dots Per lnch,每英寸点数)图像每英寸长度内的像素点数
Physical Unit:物理单位,使用的物理单位种类
Fallback Screen DPl:备用DPI,当找不到设备DPI时,使用此值
Default Sprite DPl:默认图片DPI
计算公式
根据DPI算出新的t(单位参考像素)Reference Pixels Per Unit
新单位参考像素 = 单位参考像素*Physical Unit/Default Sprite DPl
再使用模式一:
恒定像素模式的公式进行计算
原始尺寸 = 图片大小(像素)/(Pixels Per Unit/新单位参考像素)
总结
恒定物理模式
它不会让UI控件进行分辨率大小自适应
会让UI控件始终保持设置的尺寸大小显示
而且会根据设备DPI进行计算,让在不同设备上的显示大小更加准确
一般在进行游戏开发极少使用这种模式
恒定像素模式和恒定物理模式区别
相同点:使用他们不会进行分辨率大小自适应他们都不会进行缩放,图片有多大显示
不同点:相同尺寸不同DPI设备像素点区别,像素点越多细节越多
同样为5像素,DPI较低的设备上看起来的尺寸可能会大于DPI较高的设备
图集
为什么要打图集
打图集的目的就是减少 Drawcall 提高性能
Dc就是CPU通知GPU进行一次渲染的命令如果Dc次数较多会导致游戏卡顿
我们可以通过打图集,将小图合并成大图,将本应n次的Dc变成1次Dc来提高性能
在 Unity2022 中打开自带的打图集功能
在工程设置面板中打开功能
Edit --> Project Setting --> Editor
Sprite Packer(精灵包装器,可以通过 Unity 自带图集工具生成图集)
- Disabled:选择此模式可禁用当前项目中的 Sprite Atlas 打包
- Sprite Atlas V1 - Enabled for Builds 选择此模式可让 Unity 仅在发布版本时将 Sprite 打包到 Sprite Atlas 中。Editor 和 Play 模式引用原始源纹理,而不是 Sprite Atlas 中的纹理。
- Sprite Atlas V1 - Always Enabled 默认情况下,此选项处于启用状态。选择此模式可让 Unity 将选定的纹理打包到 Sprite Atlas 中,并且 Sprites 在运行时引用打包的纹理。但是,Sprites 将在编辑模式下引用原始解压缩的纹理。
- 如果选择 Sprite Atlas V2 - Enabled,则在 Edit 和 Play 模式下,Sprite 将始终使用 Sprite Atlas 作为其纹理源。
- 如果选择 Sprite Atlas V2 - Enabled for Builds,则 Unity 仅在构建 Player、AssetBundle 或 Addressable 构建脚本时打包 Sprite Atlas。当编辑器处于编辑模式时,精灵会继续使用其原始纹理,而不是来自打包的精灵图集的纹理。
注意:从 Unity 2022.2 开始,编辑器的 Sprite Atlas 模式默认设置为 Sprite Atlas V2 - 启用。Sprite Atlas V2 使用 AssetDatabase V2 (ADBV2) 公开的功能,例如缓存服务器支持,而原始 Sprite Atlas 系统不支持这些功能。
图集创建
在 Project 窗口中右键选择 Create --> 2D --> Sprite Atlas,创建图集
在UI图集中建议不要勾选。
- Allow Rotation:选中此复选框允许在 Unity 将精灵打包到精灵图集时旋转精灵。这样可以最大限度提高组合后的纹理中的精灵密度,并且默认情况下会启用此选项。如果精灵图集包含画布 UI 元素纹理,请禁用此选项,因为 Unity 在打包期间旋转精灵图集中的纹理时,也会在场景中旋转它们的方向。
- Tight Packing:选中此复选框可根据精灵轮廓而非默认矩形轮廓来打包精灵。这样可以最大限度提高组合后的纹理中的精灵密度,并且默认情况下会启用此选项。
代码加载
// 加载图集
SpriteAtlas sa = Resources.Load<SpriteAtlas>("MyAlas");
// 从图集中加载指定名字的小图
sa.GetSprite("bk");
UGUI 进阶
目前所有的控件都只提供了常用的事件监听列表
如果想做一些类似长按,双击,拖拽等功能是无法制作的,或者想让 Image 和 Text,RawImage 三大基础控件能够响应玩家输入也是无法制作的
而事件接口就是用来处理类似问题,让所有控件都能够添加更多的事件监听来处理对应的逻辑
事件接口
接口 - 函数 - 函数说明
接口函数的参数:PointerEventData
常用事件接口
- IPointerEnterHandler - OnPointerEnter - 当指针进入对象时调用 (在移动设备上该函数没有用,仅适用于鼠标进入)
- IPointerExitHandler - OnPointerExit - 当指针退出对象时调用 (鼠标离开)
- IPointerDownHandler - OnPointerDown - 在对象上按下指针时调用 (按下)
- IPointerUpHandler - OnPointerUp - 松开指针时调用(在指针正在点击的游戏对象上调用)(抬起)
- IPointerClickHandler - OnPointerClick - 在同一对象上按下再松开指针时调用 (点击)
- IBeginDragHandler - OnBeginDrag - 即将开始拖动时在拖动对象上调用 (开始拖拽)
- IDragHandler - OnDrag - 发生拖动时在拖动对象上调用 (拖拽中)
- IEndDragHandler - OnEndDrag - 拖动完成时在拖动对象上调用 (结束拖拽)
不常用事件接口
了解就好
- IInitializePotentialDragHandler - OnInitializePotentialDrag - 在找到拖动目标时调用,可用于初始化值
- IDropHandler - OnDrop - 在拖动目标对象上调用
- IScrollHandler - OnScroll - 当鼠标滚轮滚动时调用
- IUpdateSelectedHandler - OnUpdateSelected - 每次勾选时在选定对象上调用
- ISelectHandler - OnSelect - 当对象成为选定对象时调用
- IDeselectHandler - OnDeselect - 取消选择选定对象时调用
- IMoveHandler - OnMove - 发生移动事件(上、下、左、右等)时调用
- ISubmitHandler - OnSubmit - 按下 Submit 按钮时调用
- ICancelHandler - OnCancel - 按下 Cancel 按钮时调用
PointerEventData 参数的关键内容
父类:BaseEventData
- pointerId: 鼠标左右中键点击鼠标的 ID,通过它可以判断右键点击
- 左键:-1
- 右键:-2
- 中键:-3
- position:当前指针位置(屏幕坐标系)
- pressPosition:按下的时候指针的位置
- delta:指针移动增量
- clickCount:连击次数
- clickTime:点击时间,得到的是点击时当前系统时间
- pressEventCamera:最后一个 OnPointerPress 按下事件关联的摄像机
- enterEventCamera:最后一个 OnPointerEnter 进入事件关联的摄像机
好处:
- 需要监听自定义事件的控件挂载继承实现了接口的脚本就可以监听到一些特殊事件
- 可以通过它实现一些长按,双击拖拽等功能
坏处:
- 不方便管理,需要自己写脚本继承接口挂载到对应控件上,比较麻烦
EventTrigger 事件触发器
事件触发器是 EventTrigger 组件,它是一个集成了所有事件接口的脚本
它可以让我们更方便的为控件添加事件监听
拖拽 GameObject 使用事件触发器
将写好的函数脚本拖到一个 GameObject,将其拖到 EventTrigger 组件中,类似为 UI 控件添加事件监听的操作
代码控制
//挂载了EventTrigger的对象
public EventTrigger etXuli;
start()
{
//申明一个希望监听的事件对象
EventTrigger.Entry etDown = new EventTrigger.Entry();
//申明事件的类型
etDown.eventID = EventTriggerType.PointerDown;
//监听函数关联
etDown.callback.AddListener(data =>
{
print("点击");
});
//把申明好的事件对象加入到 EventTrigger当中
etXuli.triggers.Add(etDown);
}
RectTransformUtility
RectTransformUtility 公共类是一个 RectTransform 的辅助类,主要用于进行一些 坐标的转换等等操作
其中对于我们目前来说,最重要的函数是将屏幕空间上的点,转换成 UI 本地坐标下的点
将屏幕坐标转换为UI本地坐标系下的点
方法:
RectTransformUtility.ScreenPointToLocalPointInRectangle
- 参数一:相对父对象
- 参数二:屏幕点
- 参数三:摄像机
- 参数四:最终得到的点
// 一般配合拖拽事件使用
Vector2 nowPos;
RectTransformUtility.ScreenPointToLocalPointInRectangle(
transform.parent.transform as RectTransform,
eventData.position,
eventData.enterEventCamera,
out nowPos);
this.transform.localPosition = nowPos;
Mask 遮罩
在不改变图片的情况下,让图片在游戏中只显示其中的一部分
实现遮罩效果的关键组件是 Mask 组件,通过在父对象上添加 Mask 组件即可遮罩其子对象,一般配合 Image 使用
Show Mask Graphic:是否显示 Mask 遮罩
注意:
- 想要被遮罩的 Image 需要勾选 Maskable
- 只要父对象添加了 Mask 组件,那么所有的 UI 子对象都会被遮罩
- 遮罩父对象图片的制作,不透明的地方显示,透明的地方被遮罩
模型和粒子显示在 UI 前方
模型显示在 UI 前方
方法一:直接用摄像机渲染 3D 物体
Canvas 的渲染模式不能为覆盖模式 Overlay
摄像机模式和世界(3D)模式都可以让模型显示在 UI 之前(Z 轴在 UI 元素之前即可)
注意:
- 摄像机模式时建议用专门的摄像机渲染 UI 相关
- 面板上的 3D 物体建议也用 UI 摄像机进行渲染,创建在 Canvas 下,层级设置为 UI
UI摄像机的 Clear Flags 选 Depth only ,culling Mask 只选 UI 层。
主摄像机的 culling Mask 去除UI层
方法二:将 3D 物体渲染在图片上,通过图片显示,只适用于一个模型的显示,否则多个摄像机会浪费性能
专门使用一个摄像机渲染 3D 模型,将其渲染内容输出到 Render Texture 上,类似小地图的制作方式
再将渲染的图显示在 UI 上
该方式不管 Canvas 的渲染模式是哪种都可以使用
注意:
- 相机渲染模式为 Solid Color,背景颜色为纯黑
- 若渲染模式为 Depth Only,则模型移动时会出现重影
- 遮罩层级设置为 Model,同时把需要显示的模型的 Layer 层级也设置为 Model
新建一个Camera
修改模型的 Layer
创建 Render Texture 并拖入负责渲染模型的摄像机中
创建一个 RawImage 显示渲染的模型。
总结
方法一适合显示多个模型,方法二适合显示单个模型
粒子特效显示在 UI 前方
粒子特效的显示和 3D 物体类似
注意:
- 在摄像机模式下时
- 可以在粒子组件的 Renderer 相关参数中改变排序层 Sorting Layer ID 和 Order In Layer,让粒子特效始终显示在其之前不受 Z 轴影响
异形按钮
异形按钮就是图片形状不是传统矩形的按钮
添加子对象让异形按钮能够准确点击
按钮之所以能够响应点击,主要是根据图片矩形范围进行判断的
它的范围判断是自下而上的,意思是如果有子对象图片,子对象图片的范围也会算为可点击范围
那么我们就可以用多个透明图拼凑不规则图形作为按钮子对象用于进行射线检测
通过代码改变图片的透明度响应阈值
第一步:修改图片参数,开启 Read / Write Enabled 开关
第二步:通过代码修改图片的响应阈值
该参数含义:指定一个像素必须具有的最小 alpha 值,以变能够认为射线命中了图片
当像素点 alpha 值小于了,该值就不会被射线检测了
public Image img;
img.alphaHitTestMinimumThreshold = 0.1f;
自动布局组件
虽然 UGUI 的 RectTransform 已经非常方便的可以帮助我们快速布局,但 UGUI 中还提供了很多可以帮助我们对 UI 控件进行自动布局的组件,他们可以帮助我们自动的设置 UI 控件的位置和大小等
自动布局的工作方式一般是:自动布局控制组件 + 布局元素 = 自动布局
自动布局控制组件:Unity 提供了很多用于自动布局的管理性质的组件用于布局
布局元素:具备布局属性的对象们,这里主要是指具备 RectTransform 的 UI 组件
布局元素的布局属性
选中 UI 元素,以 Image 为例,查看 Inspector 面板的底部
要参与自动布局的布局元素必须包含布局属性,布局属性主要有以下几条:
- Minmum width / height:该布局元素应具有的最小宽度 / 高度
- Preferred width / height:在分配额外可用宽度之前,此布局元素应具有的宽度 / 高度
- Flexible width / height:此布局元素应相对于其同级而填充的额外可用宽度 / 高度的相对量
在进行自动布局时 都会通过计算布局元素中的这 6 个属性得到控件的大小位置
在布局时,布局元素大小设置的基本规则是:
- 首先分配最小大小 Minmum width / height
- 如果父类容器中有足够的可用空间,则分配 Preferred width / height
- 如果上面两条分配完成后还有额外空间,则分配 Flexible width / height
一般情况下布局元素的这些属性都是 0,但是特定的 UI 组件依附的对象布局属性会被改变,比如 Image 和 Text
一般情况下我们不会去手动修改他们,但是如果你有这些需求,可以手动添加一个 LayoutElement 组件,可以修改这些布局属性
水平垂直布局组件
水平垂直布局组件,将子对象并排或者竖直的放在一起
组件名:Horizontal Layout Group 和 Vertical Layout Group
参数相关:
- Padding:左右上下边缘偏移位置
- Spacing:子对象之间的间距
- ChildAlignment:九宫格对齐方式
- Control Child Size:是否控制子对象的宽高
- Use Child Scale:在设置子对象大小和布局时,是否考虑子对象的缩放
- Child Force Expand:是否强制子对象拓展以填充额外可用空间
网格布局组件
网格布局组件,将子对象当成一个个的格子设置他们的大小和位置
组件名:Grid Layout Group
参数相关:
- Padding:左右上下边缘偏移位置
- Cell Size:每个格子的大小
- Spacing:格子间隔
- Start Corner:第一个元素所在位置(4 个角)
- Start Axis:沿哪个轴放置元素;Horizontal 水平放置满换行,Vertical 竖直放置满换列
- Child Alignment:格子对其方式(9 宫格)
- Constraint:行列约束
- Flexible:灵活模式,根据容器大小自动适应
- Fixed Column Count:固定列数
- Fixed Row Count:固定行数
内容大小适配器
内容大小适配器,它可以自动的调整 RectTransform 的长宽来让组件自动设置大小
一般在 Text 上使用,或者配合其它布局组件一起使用
组件名:Content Size Fitter
参数相关:
- Horizontal Fit:如何控制宽度
- Unconstrained:不根据布局元素伸展
- Min Size:根据布局元素的最小宽高度来伸展
- Preferred Size:根据布局元素的偏好宽度 Preferred width 来伸展宽度
- Vertical Fit:如何控制高度
- Unconstrained:不根据布局元素伸展
- Min Size:根据布局元素的最小宽高度来伸展
- Preferred Size:根据布局元素的偏好高度 Preferred height 来伸展高度
宽高比适配器
宽高比适配器让布局元素按照一定比例来调整自己的大小,使布局元素在父对象内部根据父对象大小进行适配
组件名:Aspect Ratio Fitter
参数相关:
- Aspect Mode:适配模式,如果调整矩形大小来实施宽高比
- None:不让矩形适应宽高比
- Width Controls Height:宽度不变,根据宽度和 Aspect Ratio 自动调整高度
- Height Controls Width:高度不变,根据高度和 Aspect Ratio 自动调整宽度
- Fit In Parent:自动调整宽度、高度、位置和锚点,使矩形适应父项的矩形,同时保持宽高比 Aspect Ratio,会出现“黑边”
- Envelope Parent:自动调整宽度、高度、位置和锚点,使矩形覆盖父项的整个区域,同时保持宽高比 Aspect Ratio,会出现“裁剪”
- Aspect Ratio:宽高比;宽除以高的比值
画布组 Canvas Group
如果我们想要整体控制一个面板的淡入淡出或者整体禁用,使用目前学习的知识是无法方便快捷的设置的
解决方案:为面板父对象添加 CanvasGroup 组件,即可整体控制其所有子对象
参数相关:
- Alpha:整体透明度控制
- Interactable:整体启用禁用设置
- Blocks Raycasts:整体射线检测设置
- Ignore Parent Groups:是否忽略父级 CanvasGroup 的作用