迫切需要了解一下Unity的画布功能。最近在用canvas的时候总是报错。也把这个踩坑过程记录下来。


Canvas属于Unity的UGUI,UGUI提供了强大的可视化编辑,大大提高了GUI的开发效率。

Canvas是所有UI组件的父物体,也就是说每一个UI组件都必须在Canvas下,作为Canvas的子物体,当你创建一个UI控件时,如果在Hierarchy下没有Canvas组件的话,Unity会帮你自动创建一个Canvas,并将你的UI控件置于Canvas下,Unity也会自动创建EventSystem,这个对象用来确定诸如鼠标输入的事件,这对 UI 组件来说也至关重要,比如按钮。。

这里要记录一下Canvas的三种渲染方式

unity两个相机叠加 unity两个canvas_锚点

1.Screen Space - Overlay

这种渲染模式表示 Canvas 下的所有的 UI 控件永远位于屏幕的前面 , 不管有没有相机 , UI元素永远在屏幕最前面 ,主要是2D效果。

 2. Screen Space - Camera

这种渲染模式 Canvas 和 摄像机之间有一定的距离 , 可以在摄像机和 Canvas 之间播放一些粒子特效,主要是3D效果。

3. World Space

这种模式下 Canvas 就和普通的 3D 物体一样了 , 可以控制它的大小,旋转,缩放等 , 一般用来做血条。

plus

勾选"Pixel Perfect",在Canvas中的模糊效果消失,变得相对清晰。

"Sort Order"的值用来决定不同的Canvas的层级效果,当把画布设置为worldspace后,画布及画布上的UI对象在世界空间默认也是靠Z值来决定渲染顺序的,离相机远的先渲染。


基础可以先大致了解这些。然后是用Canvas开发的过程。

一般情况下都是用Canvas开发游戏的UI界面。因为我开发的类似于一个软件,所以就让canvas一直在屏幕最前方。

所以canvas下面的panel,也就是面板。面板是一个基本组件,我们可以通过脚本打开或关闭panel。创建panel以后场景就变成了如下的半透明,因为每个panel组件里都连接一个Image组件:

unity两个相机叠加 unity两个canvas_锚点_02

unity两个相机叠加 unity两个canvas_unity_03

(在创建其他UI的时候,可以用unity两个相机叠加 unity两个canvas_锚点_04该矩形工具进行移动旋转等)


接下来说一下:Image与RawImage。这两个用的非常多,然后就是因为不太清楚,所以总是出错。

这两个组件,还有Text都是继承自MaskableGraphic。

RawImage,Raw代表生的,所以就是没被加工过的图片,RawImage只为我们提供了修改UV的方法,除此之外都是继承自MaskableGraphic的方法。

Image提供了四种ImageType:Simple(普通)、Sliced(切割)、Tiled(平铺)、Filled(填充),而且它还是布局元素(ILayoutElement),可以被各种布局组(ILayoutGroup)所包含,将它和其他布局元素进行布局。

所以从这里可以看出Image相对而言比较重量级,而RawImage比较轻量级。

下图左是Image面板,右是RawImage面板,有一点需要需要一个是Texture一个是Sprite,类型是不一样的:

unity两个相机叠加 unity两个canvas_unity_05

unity两个相机叠加 unity两个canvas_UI_06


scrollview也是一个磨人的小妖精。

顾名思义就是滚动框。刚开始创建时这样的

unity两个相机叠加 unity两个canvas_锚点_07

unity两个相机叠加 unity两个canvas_unity_08


 

unity两个相机叠加 unity两个canvas_unity_09

因为我的项目里不要滑动,所以把Horizontal和Vertical都去掉了

unity两个相机叠加 unity两个canvas_unity_10

 ,结果就变成了这样

unity两个相机叠加 unity两个canvas_unity两个相机叠加_11


Movement Type: 
Elastic表示列表拉至顶部或者底部时,还可以继续拉动一部分距离,然后在经过Elasticity的时间回复 
Clamped表示不会拉动多余的距离 
Unrestricted表示随便怎么拉,拉到那算那,也不会自动恢复。

unity两个相机叠加 unity两个canvas_Image_12

里面放置要显示的数据。这里其实最重要的是这个东西,因为总是不知道该怎么放置,感觉控制的方式好多。

unity两个相机叠加 unity两个canvas_UI_13

参考博客:

Rect Transfrom

Position, size, anchor and pivot information for a rectangle.
RectTransforms are used for GUI but can also be used for other things. It’s used to store and manipulate the position, size, and anchoring of a rectangle and supports various forms of scaling based on a parent RectTransform.

RectTransform主要提供一个矩形的位置、尺寸、锚点和中心信息以及操作这些属性的方法,同时提供多种基于父级RectTransform的缩放形式。RectTransform用于但不限于GUI。

相较于RectTransform,RectTransform提供了更强大的功能来对矩形进行操作,这主要归功于新增加的两个概念:Anchor(锚点)和Pivot(中心)。

先说pivot,其实就是相当于把钉子钉在了哪里,比如这里蓝色圈圈就是pivot:

unity两个相机叠加 unity两个canvas_锚点_14

如果对它进行旋转,就是钉子那个地方是旋转点:

unity两个相机叠加 unity两个canvas_unity两个相机叠加_15

unity两个相机叠加 unity两个canvas_锚点_16

然后是Anchor,意思是锚点。Anchor是由两个Vector2向量组成。这两个向量确定两个点,再由这两个点确定一个矩形。这个矩形的四个顶点就是矩形。

Min确定矩形左下角的归一化坐标,Max确定矩形右上角的归一化坐标。刚创建的Image,其Anchor的默认值为Min(0.5,0.5)和Max(0.5,0.5)。也就是说,Min和Max重合了,四个锚点合并成一点。锚点在Scene中的表示如下,就是这个好像蝴蝶结的东西:

unity两个相机叠加 unity两个canvas_Image_17

如果Min(0.5,0.5),Max(0.6,0.5),那么效果如下:

unity两个相机叠加 unity两个canvas_Image_18

如果Min(0.5,0.5),Max(0.6,0.6),那么效果如下:

unity两个相机叠加 unity两个canvas_锚点_19

如果Min(0,0),Max(1,0),那么效果如下:

unity两个相机叠加 unity两个canvas_Image_20

Unity提供了几个预置的Anchor设置,可以快速设置:

unity两个相机叠加 unity两个canvas_UI_21

这两个属性之间的关系是:在锚点全部重合的情况下,PosX、PosY和PosZ确定了它的Pivot相对于Anchor的位置,Width和Height确定了它的尺寸。


有了UI之后,一定要有点击反应之类的东西。那么一定要讲到Event Trigger,比如:

unity两个相机叠加 unity两个canvas_unity两个相机叠加_22

我终于知道为什么有时候我点击按钮或者图像的时候报错说NullReferenceException: Object reference not set to an instance of an object System.IO.File.WriteAllBytes (System.String path, System.Byte[] bytes)了,因为正确的是这个:

unity两个相机叠加 unity两个canvas_锚点_23

但是错误用到是预制体:

unity两个相机叠加 unity两个canvas_锚点_24

然后就不会报错了了哈哈哈哈哈。

先讲到这里。后续有什么再补充。