Creating a resizeable (endless) scrollview in Unity3d
In recent versions of Unity, a “Scrollview” UI element has been introduced. It’s very useful, but one thing that wasn’t obvious (to me, at least) was how to use it for something that has potentially infinite content. In my case, I have a message window which has text added to it at various points during the game. I wanted that text to be added to the bottom of a scroll view, but have the previous text still accessible via the vertical scroll bar.
Googling how to do this turned up a number of results. But none of them quite had the full picture of how to get it to work. So I figured I’d write this post to hopefully help future googlers, even though it’s actually pretty simple.
First, a couple of assumptions:
- I’ve tested this in Unity 5.4, but it should work about as far back as 4.6)
- These instructions are for a text only scrollview, but it can probably be easily adapted to other types of content
Ok, so here’s the instructions.
First add a Scrollview to your scene (obviously as a child of a Canvas). You’ll notice it comes with a bunch of objects, as shown in the screenshot below:
The main one we’re really interested in is “Content”. If you click on it, you’ll see it’s just an empty RectTransform. To make it into something that we can add text to, you’ll need to either click ‘Add Component’ and add a Text component, or delete it and replace it with a Text component at the same place in the hierarchy. If you do the latter (which I did, because my Text components are Prefabs, so I can keep them consistent), you’ll need to click on the ‘ScrollView’ element, and drag the new Text object into the ScrollView’s ‘Content’ variable (as seen below).
(You’ll also need to make sure the ‘Pivot’ settings on the Content object’s RectTransform are set to X=0, Y=1. This makes sure it sits at the top of the ScrollView object, and is the default for the Content object that’s created with the ScrollView).
Now click back onto the Content object, click Add Component, and add a ‘Content Size Fitter’ component. Set its Vertical Fit option to ‘Preferred Size’.
And that’s pretty much it! When you add text to the Content object, it will grow to fit the text. The Scroll View will then let you scroll around to see the text you’re interested in. That may be enough for some people, but there are a couple of things to tidy up (which I needed in my case), so I’ll explain those below.
Preventing Horizontal Scroll
You probably don’t want the Scroll View to scroll horizontally, so click on it, and uncheck the ‘Horizontal’ scroll bar. It’s likely harmless to leave this on (as your Text object, by default, will wrap text anyway), but it’s not necessary.
Adding Text Programmatically
The automatic resizing is only really useful if you’re adding text dynamically. It’s pretty straightforward to do this, but I’ll put it here for completeness. You just need to append text to the Text object. I have something like this:
string msgText = textObject.GetComponent ().text;
if (msgText != "")
msgText += "\n";
msgText += newMessage;
textObject.GetComponent ().text = msgText;
This adds a new line before each new message, which is probably what you want.
Keep latest text visible
Each time you add a new message, you probably want it displayed. But by default, the Scroll View will be at top, and the user may move it around. So to ensure new messages are always seen, do this after adding a message:
Canvas.ForceUpdateCanvases();
scrollViewObject.GetComponent().verticalNormalizedPosition = 0f;
The first line forces the Canvas to do an update. This means the message you’ve added will now be taken into account by the UI system. The second line then scrolls to the bottom. And that should be all you need!
Final Thoughts
I haven’t needed to do this, but it should be quite easy to adapt the above to do resizeable/endless scroll with other types of content. Content Size Fitter can be put on any kind of UI object. Your Content object could be a Grid Layout, for instance, and you could add things into the grid at run time. This should mean it grows as necessary, and the older content scrolled off the screen.
Anyway, feel free to give my feedback on this post and let me know if it was useful.