UGUI--基础_基础组件_上

目录

[TOC]

一、基础

1.适配小技巧–1_Pivot的应用

Pivot:

  • 名称:轴心点,
  • 说明:代表当前物体位置,是一个比例值。
  • 使用:在Inspector面板中可以直接修改;或者,更改”Center”为”Pivot”,如下图:

picture0

例子:想要中间的黑色Image适配到蓝色Image的左上角。

picture1

方法一:不使用Pivot

直接设置锚点,设置锚点的时候按住“Alt”键可以在设置锚点的同时设置物体Position。

设置之后的结果如下图:

picture2

黑色Image的Inspector面板显示如下图:

picture3

其中PosX和PosY分别为Width和Height的一半。

此法的缺点:在设置此Img的位置时候,代码中需要考虑到Img的宽高。

方法二:使用Pivot

首先将轴心点Pivot移动到左上角,然后同上一样设置锚点。

picture4

设置之后的结果如下图:

picture5

黑色Image的Inspector面板显示如下图:

picture6

此时的PosX和PosY均为0,意思是代表黑色Img位置的轴心点Pivot与锚点之间的相对位置为(0,0)。

此法的优点:不再需要在代码中考虑Img的宽高,降低代码复杂度。

2.获取UI宽高(安全方式)

//获取RectTransform
RectTransform rectTrans = transform.GetComponent<RectTransform>();
//通过RectTransform获取宽高:
rectTrans.rect.width;
rectTrans.rect.height;

3.使用蓝图模式控制UI旋转、缩放时的响应区域

蓝图模式

开启方式:在检视面板中,如下图所示:

picture7

作用:开启后,无论是旋转还是缩放UI,UI的响应区域均保持不变。

picture8

使用情景:UI存在动画,但即使是在动画播放的过程中依旧需要保持响应区域不变,则可以使用蓝图模式。

4.原始编辑模式(Raw Edit Mode)

原始编辑模式

开启方式:在检视面板中,如下图所示:

picture9

作用:作用于Anchors和Pivot,具体应用场景不详。

5.Canvas画布下三个核心组件:Canvas、Canvas Scaler、Graphic Raycaster

(1)Canvas的三种模式

picture10

  • 1.Screen Space - Overlay:

picture11

a.画布独立于场景空间存在,存在于屏幕空间;b.UI永远显示在最上层;c.画布的坐标计算基于屏幕空间,由Unity自动计算,不可在检视面板中手动调整。

Pixel Perfect:开启后,会关闭抗锯齿,抗锯齿会影响到像素,所以在像素要求严格的情况下勾选。

Sort order:排序

  • 2.Screen Space - Camera:

picture12

a.画布需要与指定相机关联(Render Camera);b.画布的坐标计算基于屏幕空间,由Unity自动计算,不可在检视面板中手动调整。

关联后:

picture13

Plane Distance:画布平面到摄像机的距离,此距离即画布深度,会影响到UI是否被游戏物体遮挡(深度剔除)。

  • 3.World Space:

同上也需要关联相机,关联后:

picture14

a.画布需要与指定相机关联(Render Camera);b.画布的坐标计算基于世界空间,可在检视面板中手动调整。

(2)三种不同UI Scale Mode下的适配

picture15

a.Constant Pixel Size模式

picture16

Constant Pixel Size模式为恒定像素大小模式,屏幕中UI元素的大小由ScaleFactor(缩放因子)和ReferencePixelsPerUnit(每Unity单位对应的像素个数)共同决定。

在此模式下需要通过脚本来动态调整ScaleFactor:脚本挂载在Canvas中

    public class ConstantScaler : MonoBehaviour
    {
        private const float SCREEN_WIDTH = 1334.0f;
        private const float SCREEN_HEIGHT = 750.0f;
        private void Start()
        {
            float wScreen = Screen.width / SCREEN_WIDTH;
            float hScreen = Screen.height / SCREEN_HEIGHT;
            //假定依据宽来适配:
            GetComponent<CanvasScaler>().scaleFactor = wScreen;
        }
    }

开发过程中,使用1334x750的Screen,如下图:

picture17

在真机运行时可能为其他分辨率,例如800x600或1920x1080等。

在编辑模式下,切换Screen为1920x1080后,如下图:

picture18

此时可以看见,并未适配成功,原因在于我们必须在运行模式下,执行Start方法中的逻辑才能调整scaleFactor。点击运行后,如下图:

picture19

此时的Canvas中的Canvas Scaler组件:

picture20

Scale Factor由1变为了1.43928(≈1920/1334),如此一来便达到了适配的效果。

b.Scale With Screen Size模式

适配比较常用的模式,会依据屏幕尺寸进行缩放。

picture21

设置分辨率为1334x750,保持和开发过程中的Game视图中的分辨率一致。

Screen Match Mode匹配模式通常选择Match Width Or Height模式,表示屏幕适配是依据屏幕宽或高,就像(1)Constant Pixel Size模式中所做的那样。然后调整Match来控制宽高适配权重。

该模式下的屏幕适配往往还需配合UI元素锚点的设置,Match常用权重值:0、0.5、0.618、1。

c.Constant Physical Size模式

恒定的物理大小模式,该模式适配是依据的屏幕物理大小,具体应用很少,此处略过。

(3)Graphic Raycaster图形射线组件

picture22

该组件负责控制管理该Canvas画布下所有UI元素的射线交互,例如按钮点击。如果移除或禁用该组件,则和射线相关的交互均会失效。

  • Ignore Reversed Graphics:是否忽略反转的图形,顾名思义,如果勾选(默认勾选)则当UI元素

Rotation中的Y大于90度,即产生了翻转,则不再受图形射线组件控制,即不再有射线交互效果。

  • Blocking Objects:阻挡对象,表示哪些对象可以阻挡UI射线。

picture23

Three D:3D指的是拥有3D碰撞体的物体,也就是说即使是UI元素,只要其拥有3D碰撞体,在此处也算作3D。

  • Blocking Mask:阻挡遮罩,设置哪些层级可以阻挡UI射线。

picture24

6.Canvas Group的使用

添加CanvasGroup组件可以统一控制自身和子物体的透明度、是否可交互、是否接受UI射线

picture25

Ignore Parent Groups:是否忽略父层级的CanvasGroup设置。

7.UI渲染层级

对UI渲染层级影响重要性由大到小如下:

(1)Camera的深度Depth值

当场景中存在多个Canvas以及多个Camera时:

picture26

若要将多个Canvas显示在统一屏幕中,则设置Canvas组件的Render ModeScreen Space - Camera并指定Render Camera

picture27

在Scene场景中两个摄像机分别渲染不同的两个Canvas,如下图:

picture28

而Game视图中,渲染的图像是由Camera的Depth值决定的,Camera的Depth值会影响Canvas的渲染顺序,Depth值越小越先渲染,后渲染的会覆盖先渲染的。

我们设置Camera的Depth值为0,MainCamera的Depth值依旧保持默认-1。

picture29

查看Game视图:

picture30

然而此时虽然显示了Camera下的Canvas,然而却没有显示MainCamera下的Canvas,原因在于Camera的Clear Flags设置为Skybox,即在渲染Camera时,会在渲染完不透明对象后渲染一次天空盒,此时渲染的天空盒会覆盖掉早先MainCamera渲染的Canvas图像。详细渲染顺序可见”Analysis-Frame Debugger“,如下图:

picture31

深度值为0的Camera在绘制图像时绘制的天空盒覆盖了深度值为-1的MainCamera绘制的Canvas图像。

解决的方式是:设置Camera的Clear FlagsDepth only

picture32

此时Game视图已经可以正常显示两个Canvas中的UI元素图像了。

picture33

(2)Canvas组件内的Sorting Layer和Order in Layer

在同一Camera下的Canvas中,要进一步规定UI渲染层级则需要使用Canvas组件。

首先,在Canvas画布中的Canvas组件内添加Sorting Layer

picture34

然后为UI元素添加Canvas组件,并勾选Override Sorting,然后可以设置Sorting LayerOrder in Layer。其中Sorting Layer为排序层级,层级越接近Default则表示越先渲染,后渲染的会覆盖先渲染的;Order in Layer为层间排序,即相同层级下再进行排序,序号越小越先渲染,同样的后渲染的会覆盖先渲染的。

例如,可以将Child的Sorting Layer设置为second,而Parent保持Default不变。

picture35

picture36

此时,原本被Parent覆盖的小图片Child渲染在Parent之上了:

picture37

(3)UI的自然层级

自然层级:在同一Canvas中越靠前的UI元素越先渲染,后渲染同样会覆盖先渲染的。不过自然层级对UI渲染先后顺序的影响会被Sorting LayerOrder in Layer强制改变,所以说UI的自然层级对于UI的渲染先后顺序的影响是最弱的。

picture38

8.Image

Image参数介绍:

picture39

Source Image:此处需设置图片类型为Sprite(2D and UI)的Texture。

Color:设置颜色,RGBA格式,可以设置参数为0~255byte类型或0~1的float类型。在代码中:byte类型的颜色为Color,float类型的颜色为Color32

Material:可以添加带有特殊shader的材质。

Raycast Target:勾选后才能接收到UI射线,才能响应UI射线交互。

Image Type:图片类型,有四种可选类型:

picture40

  • Simple:普通的单张图片
  • Sliced:经过九宫格切割的图片(常用于切割边框,保证边框的清晰度)
  • Tiled:平铺
  • Filed:填充(常用于制作技能冷却)

9.RawImage

(1)常规用法–序列帧动画

Boom动画如下:

GIF1

实现方式一:RawImage+CSharp脚本

创建RawImage,并附上Texture,然后编写脚本:

    public class RawImageAnim : MonoBehaviour
    {
        public float SizeX;
        public float SizeY;
        [Tooltip("动画持续时间")]
        public float AnimDuration;

        private RawImage mRawImage;
        private WaitForSeconds mDelay;
        private float mWidth;
        private float mHeight;

        private void Start()
        {
            mRawImage = GetComponent<RawImage>();
            mDelay = new WaitForSeconds(AnimDuration / (SizeX * SizeY * 1.0f));
            mWidth = 1.0f / SizeX;
            mHeight = 1.0f / SizeY;
            StartCoroutine(PlayAnim(true));
        }

        private IEnumerator PlayAnim(bool loop)
        {
            float u = 0f, v = 1f;
            while (true)
            {
                v -= mHeight;//v坐标可以为负,类似于竖直方向上的平铺循环,具体可以自行测试
                while (u < 0.9998f)//此处存在float计算精度问题
                {
                    mRawImage.uvRect = new Rect(u, v, mWidth, mHeight);//此处uv是图片左下角的uv坐标
                    u += mWidth;
                    yield return mDelay;
                }
                u = 0f;//重置
                if (loop == false && v <= 0f) break;//循环播放的开关
            }
        }
    }
实现方式二:Shader
Shader "Custom/序列帧动画"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
		_SizeX("水平方向上图片个数",Float) = 4
		_SizeY("竖直方向上图片个数",Float) = 4
		_AnimSpeed("动画播放速度",Range(1,100)) = 30
    }
    SubShader
    {
		//特效使用和半透明物体一样的渲染设置
        Tags { "RenderType"="Transparent" "IngoreProjector"="True" "Queue"="Transparent" }
        LOD 100

        Pass
        {
			Tags{ "LightMode"="ForwardBase" }
			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
			float _SizeX;
			float _SizeY;
			float _AnimSpeed;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				float time = floor(_Time.y * _AnimSpeed);
				float v = floor(time / _SizeX);
				float u = time - v * _SizeX;
				float2 uv = i.uv + float2(u , -v-1);//v坐标可以为负,类似于竖直方向上的平铺循环,具体可以自行测试
				uv.x /= _SizeX;
				uv.y /= _SizeY;

                fixed4 col = tex2D(_MainTex, uv);
                return col;
            }
            ENDCG
        }
    }
}

(2)常规用法–3D模型展示

需要:Render Texture、一个专门用于渲染指定3D物体的Camera、RawImage

首先,使用Camera渲染指定3D物体;

然后,指定该Camera上的Target Texture为刚新建的Render Texture

最后,将Render Texture赋值给RawImage即可。

10.Text

(1)基础介绍:

picture41

Line Spacing:行间距

Rich Text:富文本

Align By Geometry:几何对齐,勾选之后会紧紧贴合边缘。

Horizontal Overflow:水平方向是否可以超出显示,若选择Wrap(包裹)则不会超出显示。

(2)富文本

勾选Rich Text后可以在Text中编辑富文本。

  • 加粗:<b>内容</b>
  • 斜体:<i>内容</i>
  • 字体大小:<size=50>内容</size>(注意!:使用富文本设置字体的时候不能勾选Best Fit
  • 字体颜色:<color=#ff0000>内容</color>(色号表可百度搜索)

例子:

内容<b>内容</b>内容<i>内容</i>内容<b><i>内容</i></b>内容<size=50>内容</size>内容<color=#ff0000>内容</color>内容<b><i><size=55><color=#ff0000>内容</color></size></i></b>

picture42

11.图片遮罩:MaskRect Mask 2D

  • 遮罩的所用:用于限制显示区域,只在设置有遮罩的区域显示图片信息。

  • Mask:一种3D遮罩,也可用于2D物体。

    在UI部分不要使用Mask来完成遮罩效果,原因是:Mask使用模板缓冲来限制显示区域,会增加DrawCall同时会打断UI的批处理再一次增加DrawCall。

  • Rect Mask 2D:2D遮罩,在CPU阶段决定显示区域,所以不会增加DrawCall,但是不会进行UI批处理。

  • 总结:Rect Mask 2D内的ui节点不可以和外面的ui节点合并批次, 多个Rect Mask 2D之间也不可以合并批次,但是多个Mask之间内的ui节点是可以合并批次的!并且多个Mask首尾dc如果满足条件也是可以分别合并的!

补充一个Rect Mask 2D使用的Bug:

picture43

picture44

更多遮罩相关资料:

Unity Mask Use Or Not

Unity手游开发札记——使用Shader进行UGUI的优化