How do I make a 2D square that resizes to fit text?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Fupicat

I want to add a chat system to my game, where you type in what you want to say and a speech bubble appears over your head, like this:

enter image description here
I’ve got the text editor for the chat working, but I have a problem with the speech bubble. I have no idea how to resize the speech bubble to accommodate the text.
This is my setup:

enter image description here
It’s a label with a NinePatchRect as child, because if I manually resize the label, the NinePatchRect actually resizes along with it. But when I allow “autowrap” for the label, weird things start happening. First off, the rect disappears, or rather, only the inside part is rendered:

enter image description here
Also, if the text in one line is too big, the text is clipped. What I expected was that the word would split into two lines.

enter image description here
Aside from that, I would like it if the box grew upwards instead of downwards, but the priority for now is knowing why the box disappears and the text clips if it’s too long.

:bust_in_silhouette: Reply From: TheFamousRat

Hello Fupicat,

If I understood you correctly, you want the Label to resize automatically, depending on the “total” size of the text.
I found a solution that allows you to do that, while having a NinePatchRect resizing with the label node, and also with the possibility to define a minimum size for said Label.

The new layout is the following

The things the VBoxContainer does is automatically resize the Label vertically to its smallest possible size. In your case, what you want that vertical size to be is, roughly, the result of max(minLabelSize,labelSizeWithCurrentText).

If you want your NinePatchRect node to always fit the entirety of the Label, don’t forget to click on Layout (when NinePatchRect is selected, this is a tab right above the viewport) and select “FullRect”.

The only values that I modified were: checking “Autowrap” on the Label, setting “Align” to “Center”, and also defining a Minimum Size for the Label (in Control/Rect/Min Size).

I hope this helps you

Edit : Re-reading your post, I don’t think there’s a built-in method in Godot to “cut” big words in smaller words. You will have to do that via code.

That looks promising! Gonna try it out, thanks. The part about breaking a word into smaller ones isn’t really that necessary.

Fupicat | 2019-02-13 21:24

Your solution worked. Now I just need to know why the edges of the NinePatch are disappearing.

Fupicat | 2019-02-13 21:29

That is strange. Is your texture an image of a classical format ? (.jpg/.png etc.)

TheFamousRat | 2019-02-14 01:04

PNG. The imagem has rounded corners and a black border, so I offset the rect by 15px in every direction from the label to make space for it. The part of the box that is rendered is just the inside region of the Nine patch, and the rest is not rendered. If I remove the offset the borders appear inside the label.
I don’t know if I’m being very descriptive… I’ll update with some more screenshots tomorrow.

Fupicat | 2019-02-14 01:24

I think the trick is that you shouldn’t offset the Texture in the NinePatch at all. Just create a NinePatch as a child of the Label, set the Texture to what you desire and just set the Layout of the NinePatch to “FullRect”. I think an offset will mess with the Anchors and Margins

TheFamousRat | 2019-02-14 01:32

But it works if autowrap is disabled.

Fupicat | 2019-02-14 01:48

That’s very strange. Is there a way you could share a part of your project so that I could try to fix this ?

TheFamousRat | 2019-02-14 17:03

Oof, I deleted the chat functionality a while ago. I decided that I would work on more important parts of my game first. Sorry. If I come across this problem again I will provide the files.

Fupicat | 2019-02-14 19:23

No problem, whatever works for you. If my solution worked, I’d appreciate that you select it. That way it would be more likely to help another person facing the same problem.

TheFamousRat | 2019-02-15 01:34