Unity 问题 之 ScrollView ,LayoutGroup,ContentSizeFitter 一起使用时,动态变化时无法及时刷新更新适配界面的问题

这篇具有很好参考价值的文章主要介绍了Unity 问题 之 ScrollView ,LayoutGroup,ContentSizeFitter 一起使用时,动态变化时无法及时刷新更新适配界面的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Unity 问题 之 ScrollView ,LayoutGroup,ContentSizeFitter 一起使用时,动态变化时无法及时刷新更新适配界面的问题

目录

Unity 问题 之 ScrollView ,LayoutGroup,ContentSizeFitter 一起使用时,动态变化时无法及时刷新更新适配界面的问题

一、简单介绍

二、问题现象

三、问题分析

四、问题解决思路

五、案例解决实现步骤

六、案例关键代码


一、简单介绍

Unity 在开发中,记录一些报错问题,以便后期遇到同样问题处理。

有时我们在开发中,一起使用 ScrollView ,LayoutGroup,ContentSizeFitter,对于简单的排布,一般会很好的自动更新适配,但是有时候复杂了时候未必很好的自动的调整,进行很好适配。

ScrollView 在可滚动区域中显示内容。当你向ScrollView添加内容时,内容会被添加到ScrollView的内容容器(#unity-content-container)中。

Layout Group 翻译为“布局组”,从字面意思就可以理解,可以对一组元素进行动态布局,这里说的动态是,组内元素数量发生变化时,Layout Group可以智能的帮助你重新排版。

ContentSizeFitter 作为一个布局控制器,控制它自己的布局元素的大小。大小由游戏对象上的布局元素组件提供的最小或首选尺寸决定。这样的布局元素可以是图像或文本组件、布局组或布局元素组件。

值得注意的是,当一个矩形变换被缩放时——无论是通过 ContentSizeFitter 还是其他东西——缩放的范围是围绕基准值进行的。这意味着可以使用基准值来控制缩放的方向。

例如,当枢轴位于中心时,ContentSizeFitter 将在所有方向上均匀地扩展矩形变换。当枢轴位于左上角时,内容大小调整器会将矩形变换向下和向右展开。

二、问题现象

现象中,刚开始与生成布局显示是没有问题,当动态添加一些 Item 的时候,会出现 布局显示都不对,会有重叠,或者 Scroll 滑动布局显示不全的现象。

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配

三、问题分析

案例中:

这里时使用 ScrollView  进行内容过多的时候,可以进行自动滑动浏览内容,其中使用到 LayoutGroup 进行排布,ContentSizeFitter 进行画布自动适配调整大小。

值得注意的是:我这里的嵌套的使用了 LayoutGroup ,和 ContentSizeFitter ,就是Item 中的子物件中还有自动排布和自动适配大小的 LayoutGroup ,和 ContentSizeFitter 组件使用。

由于嵌套,在动态生成中,子物体中也嵌套 LayoutGroup ,和 ContentSizeFitter ,父物体中的 LayoutGroup ,和 ContentSizeFitter 进行计算的时候,就会出现计算错误的现象,布局不对,且Scroll 滑动布局显示不全的现象。

四、问题解决思路

1、Canvas 强制刷新

Canvas.ForceUpdateCanvases();

2、对于unity的gridLayout verticalLayout 或者 horizontalLayout 经常有加入新成员或者改变成员大小后,部件大小、位置不对的问题,一般来说 ,这个方法就能解决

LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform);

3、用开关 gameobject 等一帧之类的方法解决,然后处理

horizLayoutGroup.CalculateLayoutInputHorizontal();
horizLayoutGroup.CalculateLayoutInputVertical();
horizLayoutGroup.SetLayoutHorizontal();
horizLayoutGroup.SetLayoutVertical();

4、还有就是进行 ContentSizeFitter 组件可以根据其子对象的大小来自动调整父对象的大小。但是,有时在动态添加内容后,ContentSizeFitter 可能无法立即更新,可以进下面

// 手动强制更新 ContentSizeFitter
ContentSizeFitter contentSizeFitter = yourContent.GetComponent<ContentSizeFitter>();
if (contentSizeFitter != null)
{
    contentSizeFitter.SetLayoutHorizontal();
    contentSizeFitter.SetLayoutVertical();
}

5、延迟更新: 如果进行一次更新无法达到刷新的效果,在向ScrollRect添加内容后,有时需要在下一帧中更新滚动视图和滚动条的范围。这可以通过将更新放置在 LateUpdate 中实现。

  • 如果这里比较耗性能,
  • 可以试着在有数据UI变化的时候触发更新若干时间关闭更新
  • 根据需要合理调整即可
void LateUpdate()
{
    // 在 LateUpdate 中更新内容和滚动条范围
    // 更新 Content 大小
    // 更新滚动条范围
}

五、案例解决实现步骤

1、创建 Unity 工程,进行 UI 布局如下,主要是 Scroll View ,然后再 Content 添加 LayoutGroup ,和 ContentSizeFitter 组件

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配

2、要进行实例化的预制体说明,ImageGroup,和 ImageItem

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配

3、新建脚本,进行ScrollView 的Content 动态生成,开始预生成部分,然后按下空格键 Space ,进行随机生成

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配

4、把 Test 挂载到场景中,赋值父物体,和对应预制体

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配

5、运行,按下空格键Space 随机生成 Item 有时候就会出现不能及时适配更新的情况

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配

6、进行对应的处理后,这里是在 LateUpdate 进行更新

  • 如果这里比较耗性能,
  • 可以试着在有数据UI变化的时候触发更新若干时间关闭更新
  • 根据需要合理调整即可

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配

7、运行场景,不能及时更新布局问题基本解决

unity layout group刷新,Unity,unity,UI 刷新,布局更新,布局适配文章来源地址https://www.toymoban.com/news/detail-764763.html

六、案例关键代码


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

/// <summary>
/// ScrollView ,LayoutGroup,ContentSizeFitter 一起使用时,动态变化时无法及时刷新更新适配界面的问题
/// </summary>
public class Test : MonoBehaviour
{
    #region Data

    /// <summary>
    /// ImageGroup 预制体
    /// </summary>
    public GameObject ImageGroup;
    /// <summary>
    /// ImageItem 预制体
    /// </summary>
    public GameObject ImageItem;
    /// <summary>
    /// ParentTran 父物体 ImageGroup
    /// </summary>
    public Transform ParentTran;

    /// <summary>
    /// ImageGroup 列表
    /// </summary>
    List<GameObject> m_ImageGroupGoLst;

    #endregion

    #region Lifecycle function
    /// <summary>
    /// Start is called before the first frame update
    /// </summary>
    void Start()
    {
        Init();
    }

    /// <summary>
    /// Update is called once per frame
    /// </summary>
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) {
            GameObject go = GetRandomImageGroup();
            CreateImageItemGameObject(go.transform);
        }
    }

    /// <summary>
    /// LateUpdate is called once per frame
    /// </summary>
    private void LateUpdate()
    {
        // 如果这里比较耗性能,
        // 可以试着在有数据UI变化的时候触发更新若干时间关闭更新
        // 根据需要合理调整即可
        RefreshUICanvas();
    }

    #endregion

    #region Private Function

    /// <summary>
    /// 初始化生成部分队列
    /// </summary>
    void Init() {
        m_ImageGroupGoLst = new List<GameObject>();
        for (int i = 0; i < 2; i++)
        {
            GameObject go = CreateImageGroupGameObject();
            if (i == 1) {
                for (int ii = 0; ii < 4; ii++)
                {
                    CreateImageItemGameObject(go.transform);
                }
            }
            m_ImageGroupGoLst.Add(go);
        }
    }

    /// <summary>
    /// 生成 ImageGroup 实体
    /// </summary>
    /// <returns></returns>
    GameObject CreateImageGroupGameObject() {
        return GameObject.Instantiate(ImageGroup, ParentTran,false);
    }

    /// <summary>
    /// 生成 ImageItem 实体
    /// </summary>
    /// <returns></returns>
    GameObject CreateImageItemGameObject(Transform parent)
    {
        return GameObject.Instantiate(ImageItem, parent, false);
    }

    /// <summary>
    /// 随机获取 生成的 ImageGroup 实体
    /// </summary>
    /// <returns></returns>
    GameObject GetRandomImageGroup() {
        int index = Random.Range(0, m_ImageGroupGoLst.Count);
        GameObject go = m_ImageGroupGoLst[index];
        return go;
    }

    /// <summary>
    /// 刷新 UI  界面
    /// </summary>
    void RefreshUICanvas()
    {
        // 强制刷新
        Canvas.ForceUpdateCanvases();
        // Layout 重建
        LayoutRebuilder.ForceRebuildLayoutImmediate(ParentTran.GetComponent<RectTransform>());

        // contentSizeFitter 设置
        ContentSizeFitter contentSizeFitter = ParentTran.GetComponent<ContentSizeFitter>();
        if (contentSizeFitter != null)
        {
            contentSizeFitter.SetLayoutHorizontal();
            contentSizeFitter.SetLayoutVertical();
        }
    }

    #endregion
}

到了这里,关于Unity 问题 之 ScrollView ,LayoutGroup,ContentSizeFitter 一起使用时,动态变化时无法及时刷新更新适配界面的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity学习笔记——ScrollView常用技巧

    在学习UI过程中反复接触ScrollView,遇到了很多使用问题,有许多技巧需要记录下来 如果不使用横向滑动,只需要将ScrollView中的Horizontal取消即可,虽然在Unity视图中还会存在,但运行游戏后就会消失;纵向滑动条同理 另外,如果你的Content的范围设置太小,也是不会显示滑动条

    2024年02月09日
    浏览(40)
  • unity scrollview滚动到指定的位置

    方法一:通过下标 方法二:原文1 原文2 方法一没测试 这里给方法二增加注释理解 图1 图2 图3 图4

    2024年01月20日
    浏览(32)
  • Unity ScrollView循环滚动播放(有详细注释)

    首先创建一个ScrollView在UI上 在Content上挂载脚本,将ScrollView赋值给Parent。 当Content的高度大于ScrollView的容量高度时便开始滚动。 以下是脚本代码: 效果如下(结尾和开头会停留1秒):

    2024年02月07日
    浏览(30)
  • 【100个 Unity实用技能】☀️ | Unity UGUI ScrollView滑动到指定位置

    老规矩,先介绍一下 Unity 的科普小知识: Unity 是 实时3D互动内容创作和运营平台 。 包括 游戏开发 、 美术 、 建筑 、 汽车设计 、 影视 在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和

    2024年02月12日
    浏览(27)
  • 【Unity-UGUI控件全面解析】| ScrollView 滚动视图组件详解

    🎬 博客主页:https://xiaoy.blog.csdn.net 🎥 本文由 呆呆敲代码的小Y 原创,首发于 CSDN 🙉 🎄 学习专栏推荐:Unity系统学习专栏 🌲 游戏制作专栏推荐:

    2024年02月06日
    浏览(41)
  • defineProps和立即执行函数不能一起使用的问题

    最近在开发的时候碰到一个很有意思的现象,在一个组件内,我需要定义props,使用方式如下: 本来这里是没有任何问题的,但是问题出在后面的代码里,我们知道Vue3的组合式API生命周期是不存在 created 相关的钩子函数的,如果我们希望在dom实例挂载之前做一些操作,例如请

    2023年04月09日
    浏览(29)
  • 【Unity3D-UGUI系列】(十二)ScrollView 滚动视图组件详解

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 首先,介绍一个UGUI,NGUI是UGUI的前身,Unity开发团队将NGUI的开发团队收到自己开发团队

    2024年02月05日
    浏览(39)
  • 2022-11 CSS:flex布局父子宽度问题-小程序scrollView-div横向滚动字体超出隐藏-居中

    如上图第二行子元素宽度会跟随第一行宽度 解决方案: 对第二行设置: width: max-content; 使其宽度跟随自身内容 如上图,左侧宽高为112rpx,宽度不生效 解决方案: 对左侧图片设置宽高的同时, 设置最小宽高 效果如下: 例1:

    2024年02月09日
    浏览(44)
  • 微信小程序缩放图片与滑动图片:movable-view与swiper一起使用所产生的手势冲突的基本解决方案(操作过于频繁还是会出现问题,基本的使用是没有问题的)

    1.一些参数和需要用到的方法js代码注释都有了,只要复制过去看就好了 2.怎么解决这个手势冲突呢,我采用的是mina-touch插件,去监听这两种手势,当双指在的时候,长按事件就不触发,滑动的时候长按事件也要阻止,因为在不停的滑动的时候,也会长按,大概就是这么一个

    2024年02月15日
    浏览(33)
  • Unity中如何让物体和相机一起动

    Unity中开发VR或者AR应用中我们想要物体和相机跟随着进行移动,我们需要先获得相机的参数,其次我们需要修改物体的参数使得其跟随移动   使用this指针可以显示的改变本脚本下物体的参数,别忘了将该脚本挂载到物体下,就可以自动执行了

    2024年02月16日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包