View on Asset Store (opens in new tab)
Package details
- Latest version
- 1.0.1
- Last updated
- First released
- Unity version
- 6000.4.1 or later
- Package size
- 64 KB
- Files
- 24
- Views in the past week
- 10
Price tracking
- Last checked
- Tracked since
- Lowest recorded
- $24.99 on
Keywords
RowPool: Recycling Scroll View for uGUI
Only the rows on screen exist, however many entries there are. One call to Attach and your ScrollRect, your prefab and your scripts stay exactly as they are.
Affiliate link · Purchases support this site
Price history
Last 6 months
USDAsset preview
1 / 6
RowPool: Recycling Scroll View for uGUI screenshot 1
About this asset
A ScrollRect slows to a crawl long before your data does. Ten thousand rows means ten thousand GameObjects, ten thousand layout passes and a frame time nobody wants to look at.
RowPool fixes that without asking you to rebuild anything around it.
using Schnurbusch.RowPool;
RowPool.Attach(scrollRect, rowPrefab, data.Count,
(i, view) => view.GetComponent<Row>().Set(data[i]));
That is the whole integration. No interface to implement, no delegate object, no base class your row has to inherit from. Your prefab, the scripts on it and your hierarchy stay exactly as they are. If you already have a ScrollRect filled by hand, you already have everything.
WHY THIS ONE
The two established solutions in this category are good, and their own reviews say the same thing about both: "not a drop in replacement", "2-3 hours rewiring my brain". They ask you to move your data behind their model. This one asks for one line and leaves your code alone.
WHAT YOU GET
Rows of different heights, two ways. Work the size out from your data and every offset is known before anything is drawn: a jump to entry 90,000 lands on entry 90,000, and the scrollbar is honest from the first frame. Or let the built row report its own size, in which case the sizes settle as the reader scrolls, and the visible rows never move while that happens.
Several prefabs in one list. Headers, separators and entries together, each prefab with its own pool, so a header never comes back as an entry.
Grids and sideways lists. Columns divide the width between them or take a fixed size. The same list turned on its side for an inventory strip or a card picker.
Insert and remove that keep the reader's place. Add ten entries above somebody who is reading and they do not move. Optionally the entries below slide rather than snap, and they still do not move.
Chat behaviour that is right in both directions. Short content sits at the bottom. New messages arrive and the list follows them down, but only while the reader actually is at the bottom. Scroll up to read something and it leaves you there. That second half is the part that is easy to get wrong.
Gamepad and keyboard focus that survives recycling. The rows on screen are chained together explicitly, because Unity's automatic navigation picks the nearest Selectable by direction and in a recycled list that is frequently a row parked off screen. The focus is remembered as an entry rather than as an object, so a data change cannot make it vanish.
MEASURED, NOT CLAIMED
Positions are worked out from the index and a prefix sum tree, never accumulated while scrolling. Accumulating is what makes long lists drift out of place over a long session, and drift is the defect that is hardest to spot and worst to live with.
InstantiatedCount is on the component so you can watch the bound hold rather than take it on trust. Scroll a hundred thousand entries end to end and it stops climbing within the first screen.
109 tests ship inside the package, editor only so they never enter a build. They cover exactly the claims above, including that a jump across ten thousand entries lands on the pixel, that every visible index is realised exactly once at any scroll position, and that the visible rows do not move while measured sizes are corrected underneath them. Run them yourself.
WHERE IT STOPS
Named in the manual rather than discovered later. A grid uses one cell size throughout, because a line of a grid is only as big as its largest cell and that cannot be known without building every cell on it. A grid does not animate inserts, because adding one cell moves every cell after it. Measured sizes are approximate until an entry has been on screen once. This is not a table framework and not a data binding system: sorting, filtering and column widths are yours.
Unity 2021.3 or newer. uGUI only. No other packages required.
Support: [email protected]
FROM THE SAME PUBLISHER
Every Schnurbusch tool follows the same rule: one line of code, your project stays as it is, full C# source.
SettingsNow: a settings menu and key rebinding in one line
https://assetstore.unity.com/packages/tools/gui/settingsnow-settings-menu-and-key-rebinding-400724
HintOnce: first-time hints with one line of code, free
https://assetstore.unity.com/packages/tools/gui/hintonce-first-time-hints-with-one-line-of-code-396738
LocLayer: localize without refactoring
https://assetstore.unity.com/packages/tools/localization/loclayer-localize-without-refactoring-394954
All tools, manuals and what is coming next: https://schnurbusch.github.io
From the publisher's Asset Store listing.
Technical details
Setup
- One call: RowPool.Attach(scrollRect, rowPrefab, count, fill). No interface, no base class, no manager component, no scene file.
- Or RowPool.Attach(scrollRect, count, fill) and the Content's first child becomes the template.
- Window > RowPool > Check Selected ScrollRect reports what attaching would do to a ScrollRect you already have, without changing anything.
What it changes on your objects
- A layout group or a ContentSizeFitter on the Content is switched off, with a line in the console saying so.
- The Content's anchors, pivot and size are set.
- The scroll axis the list needs is switched on if it is off.
- Nothing else is touched.
Sizes
- Uniform: ItemSize and Spacing.
- UseGivenSizes(index => size): asked once per entry. Every offset is exact before anything is drawn.
- UseMeasuredSizes(estimate): taken from the built row's preferred height, measured once per entry, never again on recycle. The visible rows do not move while the estimates are corrected.
- ForgetMeasurements() when the data changes enough to change the sizes.
Layout
- Direction: Vertical or Horizontal.
- UseGrid(columns, crossSize, crossSpacing). A crossSize of zero divides the viewport evenly between the columns.
- Padding on all four sides.
- AlignToEnd: content shorter than the viewport sits at the far end.
Data
- SetCount, Refresh, RefreshItem.
- Insert(index, howMany) and RemoveAt(index, howMany) keep whatever is under the near edge exactly where it is.
- AnimationSeconds makes the entries below slide instead of snapping. Zero is off and off is the default.
- UseTemplates(templateOf, prefabs) for several kinds of row, one pool per prefab.
- OnRecycle(index, view) fires before a row leaves the screen, for stopping animations and cancelling loads.
Scrolling
- ScrollTo(index), ScrollIntoView(index), ScrollOffset.
- OffsetOf(index) and IndexAtOffset(offset).
- SaveScroll and RestoreScroll hold an entry and how far into it, not a pixel offset.
- StickToEnd and IsAtEnd for chat logs.
Gamepad and keyboard
- FollowFocus chains the visible rows explicitly and follows the focus across recycling.
- Focus(index) brings an entry into view and selects it.
- Events lets you name the EventSystem, for split screen.
Under the hood
- Positions are derived from the index and a Fenwick prefix sum tree, never accumulated while scrolling, so nothing drifts over a long session.
- Where an entry starts, which entry is at an offset, and the total size all answer in O(log n).
- One object pool per prefab. LiveCount and InstantiatedCount are public so the bound can be watched rather than trusted.
Contents
- C# source only. No prefabs, scenes, images, materials, shaders or audio.
- Four assemblies: Runtime, Editor, Demo, Tests. The Editor and Tests assemblies are editor only.
- 109 edit mode tests, inside the package.
- The demo builds its whole scene in code, so there is nothing to arrive broken.
Requirements
- Unity 2021.3 or newer.
- uGUI. No other packages required and none referenced.
- The demo uses TextMeshPro, which ships inside uGUI.
Compatibility
| Unity version | Built-in | URP | HDRP | Custom |
|---|---|---|---|---|
| 6000.4.1f1 | Compatible | Compatible | Compatible | Compatible |
No shaders, materials, images or audio, so every render pipeline works.
uGUI only. No other packages are required and none are referenced.
The demo draws its text with TextMeshPro, which ships inside uGUI. A fresh project imports the TMP essentials once. The package itself uses no text.
As listed on the Asset Store.