
前言
- 本文介紹一個UGUI關(guān)于
ScrollRect
的一個拓展插件:SuperScrollView
。 - 做項目的過程中,ScrollRect組件 的使用頻率還是挺高的,尤其是在做類似背包這種需要大量子對象的時候。
- 正常情況下,使用ScrollRect做滑動功能時,如果子對象非常多,在生成時難免會卡頓。
- 所以就需要一個循環(huán)列表,類似對象池的功能,只會加載顯示頁面中所需要的,而不是一次性全部加載完成。
【Unity 實用工具篇】 | UGUI 循環(huán)列表 SuperScrollView,快速上手使用
一、UGUI ScrollRect拓展插件:SuperScrollView
1.1 介紹
UGUI SuperScrollView
基于UGUI ScrollRect提供了易于定制的ScrollView。它是一組C#腳本,可以幫助您創(chuàng)建所需的ScrollView。這是非常強大的和高度優(yōu)化的性能。
在SuperScrollView中主要有三個組件,并實現(xiàn)了三種不一樣的循環(huán)列表形式:
- LoopListView2:適用于 橫向/縱向 簡單排列的列表視圖,類似 Vertical Layout Group / Horizontal Layout Group的使用。
- LoopGridView:適用于網(wǎng)格排列,大小相同的列表視圖,類似 GridLayout Group 的使用。
- LoopStaggeredGridView:適用于網(wǎng)格排列,但大小不相同的列表視圖,可以實現(xiàn)列表中錯列排序等特殊需求。
下面就來介紹一下這三種循環(huán)列表的使用方式,快速上手及使用。
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 快速上手使用
三種功能的組件在使用時差別不大,只不過各個組件有自己獨有的幾個參數(shù)可以選擇,包括添加子對象,初始生成子對象的數(shù)量,設(shè)置間距、偏移量和排列類型等。

功能比較簡單,可配置的參數(shù)與Unity常規(guī)的布局組件類似,使用起來很容易上手。
在演示之前先做一個不使用循環(huán)列表時的普通示例,在ScrollView下加載1000個對象。
簡單搭建一個場景,在ScrollView中添加一個item作為生成的對象。

Content上面需要掛載對應(yīng)的布局組件,這里演示掛載一個垂直布局組件。

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個對象全部被生成。

在游戲中的表現(xiàn)會出現(xiàn)明顯的卡頓現(xiàn)象,對象越多越是如此。而且后面的對象并不會顯示到玩家可以操作的視圖中,只有不斷往下滑動時才會顯示,一次性生成白白消耗了性能。
下面看下SuperScrollView的使方法及效果。
2.1 LoopListView2
與前面普通示例一樣正常創(chuàng)建一個ScrollView以及對應(yīng)的item,接著在ScrollView上面掛載LoopListView2
腳本,并在LoopListView2上面添加對應(yīng)的item對象
(需要循環(huán)生成的游戲?qū)ο?#xff09;。

item對象需要掛載LoopListViewItem2腳本,如有對應(yīng)邏輯腳本也可掛載。

這里有兩個點需要注意
1.不需要在Content上面掛載對應(yīng)的布局組件了,否則會出現(xiàn)錯亂的效果。
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();
});
//初始化循環(huán)列表
LoopListView.InitListView(0, refreshListInfo);
}
private void StartTest()
{
//刷新循環(huán)列表
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;
}
}
運行查看效果:

可以看到使用循環(huán)列表之后1000個對象并不會全部生成,而是最多生成視圖中需要展示的對象數(shù)量,在滑動時使用對象池進行重復利用并賦值。
2.2 LoopGridView
LoopGridView與LoopListView2的使用方式基本相同,掛載LoopGridView腳本,添加對應(yīng)的item并設(shè)置大小和間隔。

同樣的需要在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();
});
//初始化循環(huán)列表
LoopGridView.InitGridView(0, refreshListInfo);
}
private void StartTest()
{
//刷新循環(huán)列表
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的使用方法與前兩個也是基本相同,只不過在腳本中可以設(shè)置對象之間的間隔。
在LoopGridView中,每個對象之間的間隔都是相同的,而使用LoopStaggeredGridView時可以自由設(shè)置每行/列的間隔大小及行列數(shù),下面看下使用方法。
與前面兩種類似,還是一樣的腳本掛載方式。

測試效果如下:

使用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()
{
//刷新循環(huán)列表
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;
}
}
與前兩種不同的是,在刷新列表時需要多傳入一個參數(shù)GridViewLayoutParam,用于控制行/列數(shù)及不同行/列之間的間隔大小。
一般情況下用到這種組件的機會不多,了解相關(guān)功能參考下即可。
三、其他案例
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 還支持多個不同類型的子對象根據(jù)具體需求同時生成,用來滿足再循環(huán)列表中有不同游戲?qū)ο蟮男枨?#xff0c;下面拿LoopListView2做演示效果
與正常使用LoopListView2類似,在ScrollView上面掛載LoopListView2腳本,并在LoopListView2上面添加對應(yīng)的item對象,只不過可以根據(jù)需求添加多個子對象。
具體操作如下圖所示:

然后在使用時,可以根據(jù)自己所需的條件去指定生成不同的子對象,比如下面示例根據(jù)奇偶生成不同類型的子對象。
代碼示例如下:
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;
}
}
效果如下:

總結(jié)
- 本文演示了UGUI 中循環(huán)列表 SuperScrollView的使用方法及幾個使用示例。
- 該組件已經(jīng)在很多項目中驗證過,使用起來沒有什么問題,所以可以放心食用。
-
🎬 博客主頁:https://xiaoy.blog.csdn.net
-
🎥 本文由 呆呆敲代碼的小Y 原創(chuàng) 🙉
-
🎄 學習專欄推薦:Unity系統(tǒng)學習專欄
-
🌲 游戲制作專欄推薦:游戲制作
-
🌲Unity實戰(zhàn)100例專欄推薦:Unity 實戰(zhàn)100例 教程
-
🏅 歡迎點贊 👍 收藏 ?留言 📝 如有錯誤敬請指正!
-
📆 未來很長,值得我們?nèi)Ρ几案篮玫纳?
-
------------------??分割線??-------------------------




資料白嫖,技術(shù)互助
學習路線指引(點擊解鎖) | 知識定位 | 人群定位 |
---|
🧡 Unity系統(tǒng)學習專欄 🧡 | 入門級 | 本專欄從Unity入門開始學習,快速達到Unity的入門水平 |
💛 Unity實戰(zhàn)類項目 💛 | 進階級 | 計劃制作Unity的 100個實戰(zhàn)案例!助你進入Unity世界,爭取做最全的Unity原創(chuàng)博客大全。 |
?? 游戲制作專欄 ?? | 難度偏高 | 分享學習一些Unity成品的游戲Demo和其他語言的小游戲! |
💚 游戲愛好者萬人社區(qū)💚 | 互助/吹水 | 數(shù)萬人游戲愛好者社區(qū),聊天互助,白嫖獎品 |
💙 Unity100個實用技能💙 | Unity查漏補缺 | 針對一些Unity中經(jīng)常用到的一些小知識和技能進行學習介紹,核心目的就是讓我們能夠快速學習Unity的知識以達到查漏補缺 |