A high-performance, virtualized scroll view system for Unity. This package renders only visible items and reuses UI elements through object pooling, enabling smooth scrolling through thousands of items without performance degradation or garbage collection spikes.
- Virtualized rendering β only visible items are rendered and updated
- Object pooling β automatic item recycling with zero allocation during scrolling
- High performance β handles 10,000+ items smoothly on mobile and low-end devices
- Zero-GC runtime β no allocations during scroll updates
- Generic type-safe binding β strongly typed data β UI mapping with
ScrollRectItem<T> - Vertical and horizontal scroll directions fully supported
- Multiple layouts β works with VerticalLayoutGroup, HorizontalLayoutGroup, and GridLayoutGroup
- Smooth scrolling β built-in inertia, elasticity, and clamped movement
- Easy integration β extends Unity's UI system with familiar components
- Open Window β Package Manager
- Click the + button β Add package from git URL
- Enter the repository URL:
https://github.com/AtaYanki/GenericLoopScrollRect.git
- Wait for Unity to download and import the package
Requirements:
- Unity 6000.0 or newer
- TextMeshPro (for samples)
The virtualization system optimizes scrolling through:
- Viewport detection β calculates which items are currently visible
- Pool management β retrieves inactive items from the object pool
- Data binding β updates pooled items with correct data at runtime
- Recycling β returns off-screen items to the pool for reuse
This architecture minimizes memory footprint and eliminates GC allocations during scrolling.
Define a simple data class to represent your list items:
public class PlayerData
{
public string Name;
public int Level;
public PlayerData(string name, int level)
{
Name = name;
Level = level;
}
}Create a UI item prefab and attach a script inheriting from ScrollRectItem<T>:
using UnityEngine;
using TMPro;
using AtaYanki.GenericScrollRect;
public class PlayerItem : ScrollRectItem<PlayerData>
{
[SerializeField] private TextMeshProUGUI nameText;
[SerializeField] private TextMeshProUGUI levelText;
public override void UpdateData(PlayerData data)
{
if (data != null)
{
nameText.text = data.Name;
levelText.text = "Level " + data.Level;
}
}
}Note: The prefab must have a LayoutElement component (auto-added via RequireComponent).
Create a MonoBehaviour that inherits from ScrollRect<T>:
using System.Collections.Generic;
using UnityEngine;
using AtaYanki.GenericScrollRect;
public class PlayerListController : ScrollRect<PlayerData>
{
private List<PlayerData> _playerList = new List<PlayerData>();
public override List<PlayerData> ItemDataList => _playerList;
void Awake()
{
// Populate your data
for (int i = 0; i < 1000; i++)
{
_playerList.Add(new PlayerData($"Player {i}", i));
}
}
protected override void OnItemClick(int index)
{
Debug.Log($"Clicked: {ItemDataList[index].Name}");
}
}- Create a Scroll View via GameObject β UI β Scroll View
- Delete the default
ScrollRectcomponent - Add one of these components instead:
LoopVerticalScrollRect(for vertical scrolling)LoopHorizontalScrollRect(for horizontal scrolling)
- Add your controller script (e.g.,
PlayerListController) - Configure the controller:
- Assign the Loop Scroll Rect component
- Assign your Item Prefab (the one with
PlayerItemscript)
- Add a VerticalLayoutGroup (or HorizontalLayoutGroup) to the Content object
- Configure padding and spacing as needed
Press Play. The scroll view will automatically populate with your data and recycle items as you scroll.
// Modify your data
ItemDataList.Add(new PlayerData("New Player", 999));
// Refresh the view
UpdateView();// Scroll to index 50 with speed 1000
ScrollToCell(50, 1000);Override OnItemCreated to configure items when first instantiated:
protected override void OnItemCreated(ScrollRectItem<PlayerData> item)
{
// Configure item on first creation
item.transform.localScale = Vector3.one;
}Runtime/
βββ LoopScrollRectBase.cs # Core virtualization logic
βββ LoopScrollRect.cs # Abstract scroll implementation
βββ LoopVerticalScrollRect.cs # Vertical scroll component
βββ LoopHorizontalScrollRect.cs # Horizontal scroll component
βββ ScrollRect.cs # Generic scroll wrapper
βββ ScrollRectItem.cs # Abstract item base class
βββ LoopScrollDataSource.cs # Data provider interface
βββ LoopScrollPrefabSource.cs # Pool management interface
βββ LoopScrollSizeHelper.cs # Dynamic sizing helper
Editor/
βββ LoopScrollRectInspector.cs # Custom inspector
βββ SGMenuOptions.cs # Editor menu integration
Samples/
βββ Scenes/SampleScene.unity # Example scene
βββ Scripts/
β βββ SampleData.cs # Example data model
β βββ SampleLoopScrollRectItem.cs # Example item view
β βββ SampleLoopScrollRect.cs # Example controller
βββ UI/SampleScrollRectItem.prefab # Example prefab
Properties:
abstract List<T> ItemDataList { get; }β Override to provide your data source
Methods:
void UpdateView()β Refresh the scroll view (call after modifying data)void UpdateViewDelayed()β Refresh with 0.2s delay (useful for animations)void ScrollToCell(int index, int speed)β Scroll to specific item with speedprotected abstract void OnItemClick(int index)β Handle item click eventsprotected virtual void OnItemCreated(ScrollRectItem<T> item)β Configure new items
Properties:
int ItemIndexβ Current item index (read-only)Action<int> onClickActionβ Click callback (automatically set)
Methods:
abstract void UpdateData(T data)β Override to bind data to UI elementsvoid UpdateIndex(int index)β Updates the item's index (called internally)virtual void RefreshUI(int index)β Override for custom UI refresh logicprotected void OnItemClick()β Call this from UI button events
- Keep UpdateData() fast β avoid complex calculations or asset loading
- Use object pooling for nested elements β pool complex child objects
- Limit layout rebuilds β minimize
LayoutElementchanges during runtime - Cache references β store component references in
Awake()orStart()
-
VerticalLayoutGroup settings:
- Set Child Force Expand β Width: β, Height: β
- Configure Padding and Spacing as needed
- Enable Child Control Size β Height: β
-
HorizontalLayoutGroup settings:
- Set Child Force Expand β Width: β, Height: β
- Configure Padding and Spacing as needed
- Enable Child Control Size β Width: β
-
GridLayoutGroup settings:
- Set Cell Size to match your item dimensions
- Configure Constraint (Fixed Column/Row Count)
- Set appropriate Spacing
// β
Good: Modify data, then update view
ItemDataList.Add(newItem);
UpdateView();
// β
Good: Batch modifications
ItemDataList.AddRange(newItems);
UpdateView();
// β Bad: Updating view multiple times
ItemDataList.Add(newItem1);
UpdateView(); // Expensive!
ItemDataList.Add(newItem2);
UpdateView(); // Expensive!The package includes a functional sample demonstrating:
- Basic vertical scrolling setup
- Data model implementation (
SampleData) - Item view implementation (
SampleLoopScrollRectItem) - Controller implementation (
SampleLoopScrollRect) - Click handling and data binding
To import:
- Open Package Manager
- Find Generic Loop Scroll Rect
- Expand Samples
- Click Import next to the sample
See CHANGELOG.md for version history.
- β¨ Initial public release
- π― Core virtualization engine with object pooling
- π§ Generic type-safe item binding system
βοΈ Vertical & horizontal scroll support- π¨ GridLayoutGroup compatibility
- π± Zero-GC runtime performance
- π Complete sample scene and documentation
Issue: Items not appearing
- Ensure
LoopVerticalScrollRectorLoopHorizontalScrollRectis assigned - Check that
ItemDataListis populated beforeStart()is called - Verify item prefab has a
LayoutElementcomponent
Issue: Items displaying incorrect data
- Make sure
UpdateData()properly assigns all UI elements - Check that your data list index matches expectations
Issue: Scrolling feels choppy
- Optimize your
UpdateData()method (avoid allocations) - Reduce complexity of item prefabs
- Check that
LayoutElementsizes are set correctly
Issue: Items not recycling
- Verify
ReturnObject()is being called (handled automatically) - Check console for pool-related errors
MIT License - See LICENSE for details.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes with clear commit messages
- Submit a pull request
Areas for contribution:
- Additional sample scenes
- Performance improvements
- Bug fixes
- Documentation improvements
Found a bug or have a feature request?
- Open an issue on GitHub
- Provide Unity version, error logs, and reproduction steps
Need help integrating?
- Check the included sample scene
- Review the Quick Start guide above
- Open a discussion on GitHub
Unity, UI, ScrollView, ScrollRect, Virtualization, Object Pooling, Performance, Mobile, UGUI, List, RecyclerView, ListView