Unity 之 UGUI Layout自动布局组件介绍

902 阅读3分钟

「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战

UGUI Layout布局分为三种

Horizontal Layout Group(水平布局):对象填充总个父物体,水平会填充

Vertical Layout Group(垂直布局):垂直(高度)会填充

Grid Layout Group (网格布局):以表格的形式布局,不会填充父物体


自动布局系统提供了将元素放置在嵌套布局组(如水平组、垂直组或网格)中的方法。使用该系统还可以根据元素包含的内容自动调整元素的大小。

布局元素 (Layout Element)

元素

  • Ignore Layout:忽略布局
  • Min Width:最小的宽度;(不受父物体宽度影响 )
  • Min Height:最小的高度;
  • Preferred Width:首选的宽度;(最大不能超过父物体宽度 )
  • Preferred Height:首选的高度;
  • Flexible Width:弹性宽度; ( 只有0和大于0两种 大于0的话会自动补全宽度)
  • Flexible Height:弹性高度;
  • Layout Priority: 布局优先 (5.x版本没有这个属性)

Minimum尺寸和Preferred尺寸在常规单位中定义,而Flexible尺寸在相对单位中定义。

当布局控制器为布局元素分配宽度或高度时,按以下方式使用相应属性:

  • 首先分配最小大小。
  • 如果有足够的可用空间,则分配偏好大小。
  • 如果有额外的可用空间,则分配灵活大小。

最小大小和偏好大小以常规单位定义,而灵活大小以相对单位定义。如果任何布局元素的灵活大小大于零,则意味着将填充所有可用空间。同级的相对灵活大小值决定了每个同级填充的可用空间的比例。最常见的情况是,灵活宽度和高度仅设置为 0 或 1。

如果分配完Preferred还有剩余空间,**那么Layout Group组件会根据Flexible的比例将剩余空间分配给子元素。**假设A为1,B为3,C为0,剩余了600的空间,则A会分到150,B会分到250,而C不会分到空间。

要使Layout Group可以控制其子节点的大小,请勾选其上的Control Child Size,以上设置才能生效。


Grid Layout Group

如果单纯的时候用滑动效果可以使用Scroll Rect组件即可。但使用布局就要使用布局控件

Grid Layout Group是网格布局, 1

其实滑动依然是用的Scroll Rect。

在这里插入图片描述


在这里插入图片描述

Spacing 表示 cell之间的距离。 Cell表示格子的宽度和和高度 Start Axis 表示布局方式,有横向和纵向 Child Alignment 表示对齐方式。

注意Layout Group节点下面的所有cell节点都是不能修改Rect Transform的。因为cell可能下面会放很多图片,这样我们会用个空的gameObject来当父节点。

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class newScroll : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{
    private ScrollRect rect;
    
    //每页的比列:0/2=0  1/2=0.5  2/2=1
    float[] pages = { 0, 0.5f, 1 };

    //滑动速度
    public float smooting = 4;

    //滑动的起始坐标
    float targethorizontal = 0;

    //是否拖拽结束
    bool isDrag = false;


    void Start()
    {
        rect = transform.GetComponent<ScrollRect>();
    }

    void Update()
    {
        //拖动结束,在进行转换
        if (!isDrag)
        {
            rect.horizontalNormalizedPosition = Mathf.Lerp(rect.horizontalNormalizedPosition, targethorizontal, Time.deltaTime * smooting);
        }
    }

    /// <summary>
    /// 拖动开始
    /// </summary>
    public void OnBeginDrag(PointerEventData eventData)
    {
        isDrag = true;
    }

    /// <summary>
    /// 拖拽结束
    /// </summary>
    public void OnEndDrag(PointerEventData eventData)
    {
        isDrag = false;
        
        float posX = rect.horizontalNormalizedPosition;
        int index = 0;
        //假设离第一位最近
        float offset = Mathf.Abs(page[index] - posX);
        for (int i = 1; i < page.Length; i++)
        {
            float temp = Mathf.Abs(pages[i] - posX);
            if (temp < offset)
            {
                index = i;
                //保存当前的偏移量
                offset = temp;
            }
        }

        targethorizontal = pages[index];
    }
}