Building a UI: Lists and Text

This week I focused on the basic implementation of two UI panels; the History panel (which shows a list of historical events that have happened) and the Family panel, which shows a list of the characters that are related (by blood or marriage) to a particular character.  I also spent some time getting the text to look sharper.

Preview of history panel and flipping through past updates
Flipping through historical updates
Family Panel: List of related characters
Browsing the list of related characters

Smoothly Scrolling Lists

The main challenge was performance; I’m using ScrollRect objects in Unity and they are surprisingly slow.  I’m not just talking about the need for object pooling (where you reduce the number of game objects used to render a list by re-using a small number of them to populate just the visible portion at any one time), but in the way ScrollRect inherently functions.  To the best of my understanding a ScrollRect recalculates the layout of its contents and rebuilds each graphical element every time the scroll position is changed.  The implication is that if you’re going to use a ScrollRect and want smooth scrolling, you need to make sure it’s contents are as lightweight as possible for Unity to rebuild.  One of the components I am using liberally in the UI is the character card, a character portrait with some decoration, to give you at a glance; Faction affiliation, House affiliation, the character’s general importance (i.e. are they a leader, a ruler, etc.), the character’s happiness, your opinion of the character, and the character’s opinion of you.

Character card shows a character's portrait and their salient details
Character Card

In the History panel list, I can have up to four of these character cards per row.  The control was using an “Auto Layout” based layout, and I got a significant speed up switching to a RectTransform based layout (i.e. where I calculate the position of each element manually once rather than let Unity dynamically recalculate it each rebuild).

The other tweak that seems to have helped considerably is an implementation detail of how I was doing object pooling on the list itself.  It turns out that changing the parent of a UI element also triggers a significant amount of rebuilding, so it is cheaper to leave one or two masked out list elements past the edge of the visible area, rather than temporarily reparenting them to somewhere else until they are reused to show new items.

Sharper Text Rendering

I’m using TextMeshPro to render the text, primarily because I need the ability to embed links and sprites within the text (I’m under the impression that TextMeshPro is also generally the most robust text rendering solution available for Unity).  A weakness of all the text renderers in Unity I’ve tried is that they struggle with drawing small text sharply.  The text ends up looking quite fuzzy, rather than nicely anti-aliased but still sharp.  The only solution that I can see (at least with TextMeshPro) is to find or roll your own bitmap fonts that are of the exact size you need and use them at the explicit size they were designed for (i.e. no scaling at all of either the canvas, game object, or text component font size).  If you want text at different sizes you will need to use different bitmap fonts at each seperate size, but the results are then pixel perfect.  And past a certain size, TextMeshPro’s ability to dynamically resize a font works just fine.

Differences in text sharpness when using variable vs bitmap fonts
Click to enlarge and see the difference in text sharpness

Want to Comment?

Please share your feedback about Building a UI: Lists and Text and join in other discussions on the Star Dynasties reddit

Please follow and like: