x


ScrollView performances with huge number of GUIContents.

I am wondering if there is a better way to display a huge number of entries (1k+, or 1m+) in an area with a scroll than using GUI(Layout).BeginScrollview which get slower the more entries you have, even if only ten labels are actually displayed.

The only alternative I found is to use a slider instead of a scrollview and to display only an interval, like from slider-5 to slider+5. However, I'm not quite satisfied with that solution. Visually, it's not a smooth transition but the label just appear and disappear according to the interval. If a text is to long for the area, you won't be able to read it no matter what.

Any ideas ?

more ▼

asked Mar 18 '12 at 05:30 PM

Berenger gravatar image

Berenger
11.2k 12 19 54

(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

I had this issue some time ago. I solved it by using a fix-size item height. That way you can calculate which items are visible. I still used GUILayout, but I replaced all non-visible items with a single GUILayout.Space().

If you're interested, you can download my editor script for searching unused assets here. It's still under development, but it works very well. The only thing that's a bit of a problem is that GUILayout can't calculate the width of all items since i display only the visible ones. If your content doesn't change you can precalculate the max width at start.

edit
Here is the relevant part:

    //C#
    m_ScrollPos = GUILayout.BeginScrollView(m_ScrollPos,true,true);

    int FirstIndex = (int)(m_ScrollPos.y / m_ItemHeight);
    FirstIndex = Mathf.Clamp(FirstIndex,0,Mathf.Max(0,m_FilteredResult.UnusedAssets.Count-m_ViewCount));
    GUILayout.Space(FirstIndex * m_ItemHeight);

    for(int i = FirstIndex; i < Mathf.Min(m_FilteredResult.UnusedAssets.Count, FirstIndex+m_ViewCount); i++)
    {
        string item = m_FilteredResult.UnusedAssets[i];
        GUILayout.BeginVertical("box", GUILayout.Height(m_ItemHeight));
        // [...]
        GUILayout.EndVertical();
    }
    GUILayout.Space(Mathf.Max(0,(m_FilteredResult.UnusedAssets.Count-FirstIndex-m_ViewCount) * m_ItemHeight));

    GUILayout.EndScrollView();
more ▼

answered Mar 18 '12 at 05:59 PM

Bunny83 gravatar image

Bunny83
46.9k 12 50 210

I think it should be possible to create some generic scrollview like this for arbitrary content.

Mar 18 '12 at 06:01 PM Bunny83

This seems to work so far. Here is a script to display a sequence of integers with that technique (you can display 1 million without a difference with displaying a hundred).

Now, I'm gonna try with different sizes, like "0\n\n 123 \n" etc. Any ideas ?

[Edit] So far, sounds like the calculations needed to obtain the index of the top value will be higher than just drawing the entire array in the all scroll view ...

Mar 18 '12 at 07:07 PM Berenger

Well, if you have varient content heights you have to store them in an array. You can calculate the height with GUIStyle.CalcHeight and store it along with your content. If the content doesn't change you could store the accumulated heights. So if you have those heights:

10,20,50,30,20
you would store
10,30,80,110,130

This way each item knows it absolute starting point. If you want to be able to change the content you have to accumulate the preceding and succeeding heights at redraw.

Mar 18 '12 at 08:19 PM Bunny83

That's what I had in mind, and here is the best I could come up with. The initialization takes some time and it can't handle more than 10k, but it seems to be faster than drawing everything.

Mar 18 '12 at 08:40 PM Berenger

I think I can solve the all thing by breaking any entries into as many string as their is lines. That way, the techniques above can be used. The problem remains if their is different font sizes / pictures of different sizes though.

Mar 18 '12 at 11:14 PM Berenger
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3812
x678
x109
x65
x59

asked: Mar 18 '12 at 05:30 PM

Seen: 815 times

Last Updated: Mar 18 '12 at 11:14 PM