unity - 排行榜 - 无限循环数据(一)

289 阅读3分钟

参考转载链接:unity 无限循环数据

一、前言

ScrollView 使用指南

一、前言

学习unity,主要为了个人记录一下

将介绍如何在 Unity 中使用 ScrollView 组件

二、使用方法

GitHub地址: github.com/aillieo/Uni…

此篇在这个github的基础上进行了修改

1. 创建 Scroll View

在UI节点上创建一个Scroll View

image.png

创建后如下:

image.png

将Scroll View节点的Scroll Rect组件移除,如下:

image.png

挂上代码中的ScrollView组件或ScrollViewEx组件,我这里以ScrollViewEx组件为例:

注:ScrollViewEx继承了ScrollView的所有功能,并进行了针对性的优化,它会对item进行分页,设置适当的页面尺寸可以得到更好的性能表现

image.png

挂上组件后效果如下:

image.png

2. 设置 Scroll View 参数

2.1 调整宽高
我们先调整一下Scroll View的宽高:

image.png

2.2 删除 Scrollbar 滑块
我们看到Scroll View带了两个Scrollbar滑块,我们不想要它

image.png

可以直接把子节点下的Scrollbar Horizontal和Scrollbar Vertical删除

image.png

删除后可以看到Viewport之前给Scrollbar留了空间,现在没有Scrollbar了,我们要调节一下Viewport使其填充整个Scroll View

image.png

我们选中Viewport,把Right和Bottom都改为0

image.png

效果如下

image.png

2.3 设置 item 模板: Item Template
列表中要显示一个一个的item,得先做item模板,我们在Scroll View子节点下创建一个Image,重命名为item,并调整宽高:

image.png

效果如下:

image.png

接着选中Scroll View节点,设置Item Template为刚刚的item,并填写Default Item Size为item的宽高

image.png

2.4 设置对象池大小:Pool Size
为了防止列表item的重复创建销毁,这里用到了对象池,我们需要设置一下对象池大小Pool Size。如果一直往对象池塞对象(只塞不取),对象池满了之后,就不再继续塞对象到对象池中,我们需要设置合理的对象池大小,建议是列表可见区域能够显示的item的最大数量的2倍,这里我预估列表可见区域最多显示10个item,那么我对象池大小设置为20

image.png

2.5 设置列表排列方向
竖屏option: image.png

2.6 设置分页大小: Page Size
如果你用的是ScrollView组件就没有Page Size这个设置了,只有ScrollViewEx组件有这个设置。

为什么要设置分页呢?ScrollView中维护了一份List,用于存储item的坐标和尺寸

image.png

假设你的列表有巨量的item数据,你现在要往中间插入一个新的item,这个时候要重新计算巨量的item的坐标和尺寸,非常的耗性能,解决办法就是设置分页,每次只维护一个分页的item,大大提升性能。

建议设置为列表可见区域能够显示的item的最大数量的2倍以上,这里设置为30

image.png

2.7 其他常规设置

image.png

image.png

3. 给 item 加点元素

这是博主的效果: image.png

可以自行拟定,这种效果的结构如下:

image.png

4. 写测试代码

创建一个MyTest.cs脚本

注:TestScript.cs和TestLargeAmount.cs是原作者提供的测试脚本

image.png

脚本见底部源码和注释

5. 运行测试

我们将MyTest.cs脚本挂到Canvas上,并赋值Scroll View成员

image.png

接着,我们把item隐藏掉

image.png

6. item 直接增加间隔

在item下创建一个Image并重命名为bg,设置Anchors为stretch-strech,设置Top和Bottom位2,这样就会上下留2个单位的缝隙

image.png

三、Demo 源码

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

public class MyTest : MonoBehaviour
{
    public struct RankItemData
    {
        // 名次
        public int rank;
        // 名字
        public string name;
    }

    List<RankItemData> testData = new List<RankItemData>();

    public ScrollView scrollView;

    private void Start()
    {
        // 构造测试数据
        InitData();


        scrollView.SetUpdateFunc((index, rectTransform) =>
        {
            // 更新item的UI元素
            RankItemData data = testData[index];
            rectTransform.gameObject.SetActive(true);
            rectTransform.Find("rankText").GetComponent<Text>().text = data.rank.ToString();
            rectTransform.Find("nameText").GetComponent<Text>().text = data.name;
            // Button btn = rectTransform.Find("Button").GetComponent<Button>();
            // btn.onClick.RemoveAllListeners();
            // btn.onClick.AddListener(()=>{
            //     Debug.Log(data.name);
            // });
            // RectTransform  bg = rectTransform.Find("bg").GetComponent<RectTransform>();
            // bg.sizeDelta = new Vector2(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y - 4);
        });
        scrollView.SetItemSizeFunc((index) =>
        {
            // 返回item的尺寸
            RankItemData data = testData[index];
            if(data.rank <= 3)
            {
                return new Vector2(314, 100);
            }
            else
            {
                return new Vector2(314, 100);
            }
        });
        scrollView.SetItemCountFunc(() =>
        {
            // 返回数据列表item的总数
            return testData.Count;
        });

        scrollView.UpdateData(false);
        
    }

    private void InitData()
    {
        // 构建50000个排名数据
        for (int i = 1; i <= 1000; ++i)
        {
            RankItemData data = new RankItemData();
            data.rank = i;
            data.name = "Name_" + i;
            testData.Add(data);
        }
    }
}