Notes to myself on Unity’s content size fitter (CSF) component. It’s a layout component for UIs. Layout components decide the position and size of widgets, based on a set of rules.
While you can nudge every widget into position manually, it’s often better to let the game do it. It can recompute positions as screen sizes change, and you add and remove widgets.
Let’s start with a simple goal.
Here’s a UI thing.
The width and height of the visual container image, the thing with the border, isn’t specified manually. It’s computed, based on the contents.
Add more text, and the container should adjust automatically:
It still looks good, even though it’s just one image.
Change to a smaller font, and the container should adjust itself.
Here’s how I did it. As usual, note that I’m not a Unity expert. I can’t say what I’m doing is perfect, but it works.
Getting set up
Here are the three game objects (GOs) I used:
Let’s talk about each GO. The canvas is… well, a canvas. Nothing special about it. Here are its settings:
Panel is a child of the canvas. It has the bitmap for the rounded box thing. There’s just one bitmap, that looks good no matter its width and height. How can that be? It’s a 9-slice. Here it is in the sprite editor:
The slices at the top and bottom can be stretched horizontally, and still look good. The slices on the left and right can be stretched vertically without distortion. The middle tile can be stretched in both dimensions.
The corner tiles can’t be stretched without distortion. When Unity resizes the image to fit the content, it leaves those slices alone. It just messes with the other slices.
Here are the image’s import settings:
The sprite mode is Single, not Multiple, though it might seem Multiple is the right setting. Multiple is for sprite sheets, where there are many sprite image versions on one bitmap. We’ve got one version of the sprite, that gets carved up. Also, the mesh type should be Full Rect.
Once the bitmap is imported and sliced, we need to use it as the source image on an Image component attached to a GO. Here are the settings I used.
Note the image type is Sliced.
ContentPanel is a regular TextMesh Pro GO.
Content size fitting
I added three components:
- Content size fitter (CSF)
- Vertical layout group (VLG)
- Content size fitter
Here are the Panel’s settings:
The CSF uses Preferred for both horizontal and vertical. The VLG doesn’t try to alter the size of the child GOs. The CSFs will work that out.
Check out Panel’s Rect Transform. Some fields are grayed out because they’re computed by the CSF.
Here’s TextContent’s settings:
Again, some Rect Transform fields are disabled. Also note the warning about the parent layout group component. Thing is, when I removed the CSF here, the layout broke. I can’t say that what I’m doing is perfect, but it works.
Well, that was pretty easy. Now, what happens when Panel has several widgets? When you want the size of some to be adjusted based on their content, while others are fixed in size? Hmm…