Skip to content

Instantly share code, notes, and snippets.

@AnsisMalins
Last active October 23, 2022 23:17
Show Gist options
  • Save AnsisMalins/393ebaaa958fcb82537d33943772570e to your computer and use it in GitHub Desktop.
Save AnsisMalins/393ebaaa958fcb82537d33943772570e to your computer and use it in GitHub Desktop.
Virtualizing list view for Unity IMGUI
using System;
using System.Reflection;
using UnityEngine;
public static class GUI2
{
#if UNITY_EDITOR
private static readonly MethodInfo _internalRepaintEditorWindow = typeof(GUI).GetMethod(
"InternalRepaintEditorWindow", BindingFlags.Static | BindingFlags.NonPublic);
#endif
public static float ListView(Rect position, int itemCount, float itemHeight, float scrollPosition,
Action<int> drawItem)
{
float scrollBarWidth = GUI.skin.verticalScrollbar.fixedWidth;
Rect clientArea = position;
clientArea.width -= scrollBarWidth;
GUILayout.BeginArea(clientArea);
float visibleCount = clientArea.height / itemHeight;
int start = Mathf.Clamp(Mathf.RoundToInt(scrollPosition), 0, itemCount - 1);
int end = Mathf.Min(start + Mathf.CeilToInt(visibleCount), itemCount);
try
{
for (int i = start; i < end; i++)
drawItem(i);
}
catch (ArgumentException)
{
// If our size changes between layout and repaint, there could be a mismatch between the amount
// of items laid out and drawn, and an exception could be thrown.
}
GUILayout.EndArea();
var evt = Event.current;
if (evt.type == EventType.ScrollWheel && position.Contains(evt.mousePosition))
{
scrollPosition += evt.delta.y;
#if UNITY_EDITOR
_internalRepaintEditorWindow.Invoke(null, null);
#endif
}
scrollPosition = GUI.VerticalScrollbar(
new Rect(clientArea.xMax, position.y, scrollBarWidth, position.height),
scrollPosition, visibleCount, 0f, itemCount + (visibleCount - Mathf.Floor(visibleCount)));
return scrollPosition;
}
}
@AnsisMalins
Copy link
Author

Usage:

_scrollPosition = GUI2.ListView(new Rect(0f, 23f, position.width, position.height - 23f),
    _items.Count, itemHeight, _scrollPosition, index =>
{
    GUILayout.Label(_items[index]);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment