UnityUGUI:ScrollView的Content不能根据实际Content下的游戏物体的多少自动改变Content的宽高问题

在实际使用UGUI开发的过程中发现一个UGUI的BUG:

当Content下的子物体增加时,ScrollBar下的Handle滑条大小没有实时根据发生Content下的子物体数量发生变化。(在Hierarchy面板中右键创建UI->ScrollView,在子物体中找到Content,需要按行列布置的游戏物体都作为Content的子物体挂在Content下)

(以开发垂直的ScrollView为例)在查找问题的过程中发现:我的这个项目里Content的高小于遮罩层Viewport的的高,致使ScrollBar滑条的size一直为1的状态。调整Content的高使高大于遮罩层Viewport的的高后又发现如下问题:

在编辑模式下ScrollBar滑条的size只根据Content与遮罩层Viewport的大小比例进行了调整,而不是根据Content的子物体数量进行变换,致使了在Content下添加的子物体的总高大于Content设置的高时下拉滑条并不能全部显示的问题,并且在游戏运行时ScrollBar的Size又重新变回1了,无论怎么调整参数都无济于事。

于是自己写了一个脚本,根据Content下的子物体的个数来控制Content的宽高(原理是修改RectTransform的sizedelta),代码如下:

/*
 * 说明:挂在UGUI中ScrollView中的Content游戏物体下(在Hierarchy面板中右键创建UI->ScrollView,在子物体中找到Content)
 * 
 * 功能:解决ScrollView中Content不能根据实际Content下的游戏物体的多少自动改变Content的宽高问题
 *      以至于在Content动态添加需要排序的游戏物体时ScrollBar滑条变更不正确的问题
 *      (Content Size Fitter组件是用于文本组件时自动根据文本变更大小的组件,这里不适用)
 */

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScrollViewContentTool : MonoBehaviour
{

    /// <summary>
    /// 根据ScrollBar的类型自动调整Content的宽或高
    /// </summary>
    public enum ScrollBarType
    {
        Vertical,      //为垂直状态时需设置RectTransform的Anchors为Min(0,1),Max(1,1)
        Horizontal,    //为水平向右延伸状态时需设置RectTransform的Anchors为Min(0,0),Max(0,1)
        HorizontalAndVertical
    }

    public ScrollBarType m_barType;

    /// <summary>
    /// 该Content表示实际宽高(这里宽高大小应该为Viewport遮罩层的大小)
    /// </summary>
    public float m_ContentWidth = 0;
    public float m_ContentHeight = 0;

    /// <summary>
    /// Content下排列的游戏物体的宽和高的大小
    /// </summary>
    public Vector2 m_cellSize = Vector2.zero;

    /// <summary>
    /// Content下排列的游戏物体X轴和Y轴的间距
    /// </summary>
    public Vector2 m_Spacing = Vector2.zero;

    private RectTransform m_rectTransform = null;
    private int m_tempChildCount = 0;

    // Use this for initialization
    private void Awake()
    {
        m_rectTransform = this.GetComponent<RectTransform>();
        m_tempChildCount = this.transform.childCount;
        //if (m_tempChildCount > 0) m_ChildSize = this.transform.GetChild(0).GetComponent<RectTransform>().sizeDelta;

        if (m_barType == ScrollBarType.Horizontal)
        {
            if (m_ContentWidth == 0) Debug.LogError("请设置Content的Width!!");
            m_rectTransform.anchorMin = new Vector2(0, 0);
            m_rectTransform.anchorMax = new Vector2(0, 1);
            m_rectTransform.sizeDelta = new Vector2(m_ContentWidth, 0);
        }
        else if (m_barType == ScrollBarType.Vertical)
        {
            if (m_ContentHeight == 0) Debug.LogError("请设置Content的Height!!");
            m_rectTransform.anchorMin = new Vector2(0, 1);
            m_rectTransform.anchorMax = new Vector2(1, 1);
            m_rectTransform.sizeDelta = new Vector2(0, m_ContentHeight);
        }
        else if (m_barType == ScrollBarType.HorizontalAndVertical)
        {
            if (m_ContentHeight == 0 || m_ContentWidth == 0) Debug.LogError("请设置Content的Width和Height!!");
            m_rectTransform.anchorMin = new Vector2(0, 0);
            m_rectTransform.anchorMax = new Vector2(1, 1);
            m_rectTransform.sizeDelta = new Vector2(0, 0);
        }

        //Debug.Log(this.transform.GetChild(0).GetComponent<RectTransform>().sizeDelta);
    }

    // Update is called once per frame
    private void Update()
    {
        if (m_tempChildCount != this.transform.childCount)
        {
            Debug.Log(this.transform.parent.parent.parent.name + this.transform.childCount);
            m_tempChildCount = this.transform.childCount;
            UpdateContentSize(m_tempChildCount);
        }
    }

    /// <summary>
    /// 根据Content下子物体数量的变化更新Content的宽高
    /// </summary>
    private void UpdateContentSize(int _count)
    {
        if (m_barType == ScrollBarType.Horizontal)
        {
            if (_count * (m_cellSize.x + m_Spacing.x) > m_ContentWidth)
            {
                m_rectTransform.sizeDelta = new Vector2(_count * (m_cellSize.x + m_Spacing.x), 0);
                //Debug.Log(m_rectTransform.sizeDelta.x);
            }
        }
        else if (m_barType == ScrollBarType.Vertical)
        {
            if (_count * (m_cellSize.y + m_Spacing.y) > m_ContentHeight)
            {
                m_rectTransform.sizeDelta = new Vector2(0, _count * (m_cellSize.y + m_Spacing.y));
                //Debug.Log(m_rectTransform.sizeDelta.y);
            }
        }
        //此时的m_rectTransform.sizeDelta代表往右和往下的增量,为0时代表Content的初始大小
        else if (m_barType == ScrollBarType.HorizontalAndVertical)
        {
            if (_count * (m_cellSize.x + m_Spacing.x) > m_ContentWidth)
            {
                float width = Mathf.Abs(m_ContentWidth - _count * (m_cellSize.x + m_Spacing.x));
                m_rectTransform.sizeDelta = new Vector2(width, 0);
            }

            if (_count * (m_cellSize.y + m_Spacing.y) > m_ContentHeight)
            {
                float height = Mathf.Abs(m_ContentHeight - _count * (m_cellSize.y + m_Spacing.y));
                m_rectTransform.sizeDelta = new Vector2(0, -height);
            }
        }
    }
}


将此代码挂在Content游戏物体下即可,亲测可用。

 

 

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值