前言
- 本文介绍一个UGUI关于
ScrollRect
的一个拓展插件:SuperScrollView
。 - 做项目的过程中,ScrollRect组件 的使用频率还是挺高的,尤其是在做类似背包这种需要大量子对象的时候。
- 正常情况下,使用ScrollRect做滑动功能时,如果子对象非常多,在生成时难免会卡顿。
- 所以就需要一个循环列表,类似对象池的功能,只会加载显示页面中所需要的,而不是一次性全部加载完成。
【Unity 实用工具篇】 | UGUI 循环列表 SuperScrollView,快速上手使用
一、UGUI ScrollRect拓展插件:SuperScrollView
1.1 介绍
UGUI SuperScrollView
基于UGUI ScrollRect提供了易于定制的ScrollView。它是一组C#脚本,可以帮助您创建所需的ScrollView。这是非常强大的和高度优化的性能。
在SuperScrollView中主要有三个组件,并实现了三种不一样的循环列表形式:
- LoopListView2:适用于 横向/纵向 简单排列的列表视图,类似 Vertical Layout Group / Horizontal Layout Group的使用。
- LoopGridView:适用于网格排列,大小相同的列表视图,类似 GridLayout Group 的使用。
- LoopStaggeredGridView:适用于网格排列,但大小不相同的列表视图,可以实现列表中错列排序等特殊需求。
下面就来介绍一下这三种循环列表的使用方式,快速上手及使用。
1.2 效果展示
1.3 使用说明及下载
Unity Asset Store下载地址:https://assetstore./packages/tools/gui/ugui-super-scrollview-86572
CSDN下载地址:SuperScrollView
白嫖地址:VX搜我名字,回复【素材资源】
使用插件的方式有多种:
- 将下载好的SuperScrollView资源文件直接放到我们的项目Assets文件夹下即可。
- 可以通过Unity中的 Window -> Package Manager 中导入,选择添加下载好的插件,或者使用URL直接添加都可以。
二、SuperScrollView 快速上手使用
三种功能的组件在使用时差别不大,只不过各个组件有自己独有的几个参数可以选择,包括添加子对象,初始生成子对象的数量,设置间距、偏移量和排列类型等。
功能比较简单,可配置的参数与Unity常规的布局组件类似,使用起来很容易上手。
在演示之前先做一个不使用循环列表时的普通示例,在ScrollView下加载1000个对象。
简单搭建一个场景,在ScrollView中添加一个item作为生成的对象。
Content上面需要挂载对应的布局组件,这里演示挂载一个垂直布局组件。
Item对象上面挂载一个测试脚本TestItem.cs
using UnityEngine; using UnityEngine.UI; public class TestItem : MonoBehaviour { public Image ImgIcon; public Text TxtName; public void SetData(int _index) { TxtName.text = $"测试:<color=#F55F55>{_index}</color>"; } }
测试生成1000个对象脚本如下:
using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LoopViewDemo : MonoBehaviour { public Button button; public Transform testContent; public GameObject testItem; private void Awake() { button.onClick.AddListener(() => { StartTest(); }); } private void StartTest() { for (int i = 0; i < 1000; i++) { GameObject go = GameObject.Instantiate(testItem, testContent); var itemInfo = go.GetComponent<TestItem>(); itemInfo.SetData(i); } } }
此时运行游戏,点击开始按钮,可以看到1000个对象全部被生成。
在游戏中的表现会出现明显的卡顿现象,对象越多越是如此。而且后面的对象并不会显示到玩家可以操作的视图中,只有不断往下滑动时才会显示,一次性生成白白消耗了性能。
下面看下SuperScrollView的使方法及效果。
2.1 LoopListView2
与前面普通示例一样正常创建一个ScrollView以及对应的item,接着在ScrollView上面挂载LoopListView2
脚本,并在LoopListView2上面添加对应的item对象
(需要循环生成的游戏对象)。
item对象需要挂载LoopListViewItem2脚本,如有对应逻辑脚本也可挂载。
这里有两个点需要注意
1.不需要在Content上面挂载对应的布局组件了,否则会出现错乱的效果。
2.ScrollView组件如果需要保留滑动条,则不能选择Auto Hide And Expand Viewport。
使用LoopListView2的代码如下:
using SuperScrollView; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LoopViewDemo : MonoBehaviour { public Button button; public LoopListView2 LoopListView; private void Awake() { button.onClick.AddListener(() => { StartTest(); }); //初始化循环列表 LoopListView.InitListView(0, refreshListInfo); } private void StartTest() { //刷新循环列表 LoopListView.SetListItemCount(1000, true); } private LoopListViewItem2 refreshListInfo(LoopListView2 loopListView, int index) { if (index < 0 || index > 1000) return null; LoopListViewItem2 item = loopListView.NewListViewItem("item"); LoopTestItem _itemInfo = item.GetComponent<LoopTestItem>(); _itemInfo.SetData(index); return item; } }
运行查看效果:
可以看到使用循环列表之后1000个对象并不会全部生成,而是最多生成视图中需要展示的对象数量,在滑动时使用对象池进行重复利用并赋值。
2.2 LoopGridView
LoopGridView与LoopListView2的使用方式基本相同,挂载LoopGridView脚本,添加对应的item并设置大小和间隔。
同样的需要在item上面添加LoopGridViewItem脚本。
测试效果如下,同时只会生成部分对象,不会全部生成。
使用LoopGridView的代码如下:
using SuperScrollView; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LoopViewDemo : MonoBehaviour { public Button button; public LoopGridView LoopGridView; private void Awake() { button.onClick.AddListener(() => { StartTest(); }); //初始化循环列表 LoopGridView.InitGridView(0, refreshListInfo); } private void StartTest() { //刷新循环列表 LoopGridView.SetListItemCount(1000, true); } private LoopGridViewItem refreshListInfo(LoopGridView loopListView, int arg2, int arg3, int arg4) { if (arg2 < 0 || arg2 > 1000) return null; LoopGridViewItem item = loopListView.NewListViewItem("item"); LoopTestItem _itemInfo = item.GetComponent<LoopTestItem>(); _itemInfo.SetData(arg2); return item; } }
2.3 LoopStaggeredGridView
LoopStaggeredGridView的使用方法与前两个也是基本相同,只不过在脚本中可以设置对象之间的间隔。
在LoopGridView中,每个对象之间的间隔都是相同的,而使用LoopStaggeredGridView时可以自由设置每行/列的间隔大小及行列数,下面看下使用方法。
与前面两种类似,还是一样的脚本挂载方式。
测试效果如下:
使用LoopStaggeredGridView的代码如下:
using SuperScrollView; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LoopViewDemo : MonoBehaviour { public Button button; public Button button2; public LoopStaggeredGridView loopStaggeredGridView; private void Awake() { button.onClick.AddListener(() => { StartTest(); }); button2.onClick.AddListener(() => { UpdateTest(); }); GridViewLayoutParam layoutParam = new GridViewLayoutParam() { mColumnOrRowCount = 3, mItemWidthOrHeight = 1, mCustomColumnOrRowOffsetArray = new float[] { 0, 222, 666 } }; loopStaggeredGridView.InitListView(0, layoutParam, refreshStaggeredListInfo); } private void StartTest() { //刷新循环列表 loopStaggeredGridView.SetListItemCount(1000, true); } private void UpdateTest() { GridViewLayoutParam layoutParam = new GridViewLayoutParam() { mColumnOrRowCount = 4, mItemWidthOrHeight = 1, mCustomColumnOrRowOffsetArray = new float[] { 0, 444, 666,1111 } }; loopStaggeredGridView.ResetGridViewLayoutParam(1000, layoutParam); } private LoopStaggeredGridViewItem refreshStaggeredListInfo(LoopStaggeredGridView loopListView, int index) { if (index < 0 || index > 1000) return null; LoopStaggeredGridViewItem item = loopListView.NewListViewItem("item"); LoopTestItem _itemInfo = item.GetComponent<LoopTestItem>(); _itemInfo.SetData(index); return item; } }
与前两种不同的是,在刷新列表时需要多传入一个参数GridViewLayoutParam,用于控制行/列数及不同行/列之间的间隔大小。
一般情况下用到这种组件的机会不多,了解相关功能参考下即可。
三、其他案例
SuperScrollView 还提供了很多种不同的展示效果,具体可以在官方案例查看,这里演示几种作为参考。
3.1 滚动时大小变化
完整代码如下:
using SuperScrollView; using UnityEngine; public class LoopListViewExample : MonoBehaviour { [SerializeField] private LoopListView2 m_view = null; private void Start() { m_view.InitListView(100, OnUpdate); } private void LateUpdate() { m_view.UpdateAllShownItemSnapData(); int count = m_view.ShownItemCount; for (int i = 0; i < count; ++i) { var itemObj = m_view.GetShownItemByIndex(i); var itemUI = itemObj.GetComponent<LoopTestItem>(); var amount = 1 - Mathf.Abs(itemObj.DistanceWithViewPortSnapCenter) / 720f; var scale = Mathf.Clamp(amount, 0.4f, 1); itemUI.SetScale(scale); } } private LoopListViewItem2 OnUpdate(LoopListView2 view, int index) { if (index < 0 || index > 100) return null; var itemObj = view.NewListViewItem("item"); var itemUI = itemObj.GetComponent<LoopTestItem>(); itemUI.SetData(index); return itemObj; } }
using UnityEngine; using UnityEngine.UI; public class LoopTestItem : MonoBehaviour { public Transform RootTrans; public Image ImgIcon; public Text TxtName; public void SetData(int _index) { TxtName.text = $"测试:<color=#F55F55>{_index}</color>"; } public void SetScale(float scale) { RootTrans.GetComponent<CanvasGroup>().alpha = scale; RootTrans.transform.localScale = new Vector3(scale, scale, 1); } }
需要在子对象挂载的脚本中添加一个SetScale方法用来控制大小及各种变化。
3.2 多个不同类型子对象
SuperScrollView 还支持多个不同类型的子对象根据具体需求同时生成,用来满足再循环列表中有不同游戏对象的需求,下面拿LoopListView2做演示效果
与正常使用LoopListView2类似,在ScrollView上面挂载LoopListView2脚本,并在LoopListView2上面添加对应的item对象,只不过可以根据需求添加多个子对象。
具体操作如下图所示:
然后在使用时,可以根据自己所需的条件去指定生成不同的子对象,比如下面示例根据奇偶生成不同类型的子对象。
代码示例如下:
using SuperScrollView; using UnityEngine; public class LoopListViewExample : MonoBehaviour { [SerializeField] private LoopListView2 m_view = null; private void Start() { m_view.InitListView(100, OnUpdate); } private LoopListViewItem2 OnUpdate(LoopListView2 view, int index) { if (index < 0 || index > 100) return null; var itemType = view.NewListViewItem("itemType1"); if (index % 2 == 0) { itemType = view.NewListViewItem("itemType1"); } else { itemType = view.NewListViewItem("itemType2"); } var itemUI = itemType.GetComponent<LoopTestItem>(); itemUI.SetData(index); return itemType; } }
效果如下:
总结
- 本文演示了UGUI 中循环列表 SuperScrollView的使用方法及几个使用示例。
- 该组件已经在很多项目中验证过,使用起来没有什么问题,所以可以放心食用。
博客主页:https://xiaoy.blog.csdn.net
本文由 呆呆敲代码的小Y 原创
学习专栏推荐:Unity系统学习专栏
游戏制作专栏推荐:游戏制作
Unity实战100例专栏推荐:Unity 实战100例 教程
欢迎点赞
收藏
留言
如有错误敬请指正!
未来很长,值得我们全力奔赴更美好的生活
——————
分割线
————————-
资料白嫖,技术互助
学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
入门级 | 本专栏从Unity入门开始学习,快速达到Unity的入门水平 | |
进阶级 | 计划制作Unity的 100个实战案例!助你进入Unity世界,争取做最全的Unity原创博客大全。 | |
难度偏高 | 分享学习一些Unity成品的游戏Demo和其他语言的小游戏! | |
互助/吹水 | 数万人游戏爱好者社区,聊天互助,白嫖奖品 | |
Unity查漏补缺 | 针对一些Unity中经常用到的一些小知识和技能进行学习介绍,核心目的就是让我们能够快速学习Unity的知识以达到查漏补缺 |