How do I dynamically set the dialog box (and corresponding text box) size to fit varying dialog?

0 favourites
  • 7 posts
From the Asset Store
Template for a generic save / load system, fully documented in comments and video
  • I have a dialog system set up but I'm having trouble sizing the box to fit varying amounts of text per line. Most lines turn out just fine.

    But some look strange.

    Like here the text will not be centered and it will not display all the dialog. Words at the end will be missing (in this case it's missing the character's name and a ?).

    Does anyone have any ideas how to always make the text box the right size to fit the amount of text in a given line?

    What I have now is on the "displayLine" function:

    DialogText Set Height to max(12, ceil(len(Dialog.At(lineOfDialog)) / 35) * 14)

    DialogTextBackground Set Height to max(12, ceil(len(Dialog.At(lineOfDialog)) / 35) * 14 + 6)

  • So the issues are the textBox isn't long enough and the text isn't being centered vertically?

    The width should be simple enough. For fixed width fonts like spritefonts it would be len(text)*characterWidth. For normal text objects there is a textWidth expression, but it only gives the width of the previous frame (booo!). You could also do word warping. I think this is handled by the object, but I haven't checked.

    Vertical centering is just a matter of moving things up and down. So if you know you have two lines you can leave things as they are, and if you have only one line you can move the line down by half a the height of a letter to center it. You may also be able to utilize the vertical alignment property.

    There is an issue if you use lines of dialog with newlines, you'd have to look at the width of each line and use the longest one for the width. Here's it in pseudocode:

    var width = 0
    var height = 0
    repeat tokencount(dialog, newline) times
    -- set width to max(width, len(tokenat(dialog, loopindex, newline)*characterWidth)
    -- add characterHeight to height

    I'll probably stop there, hopefully some of that will help.


    Here's an example you can pick apart:

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Ah! Tokencount. And then use "newline" as a separator.

    What I have are paragraphs stored in an array. I was hoping there would be a way to automatically get the height (or in this case line count based on number of characters). Since ten "." and ten "X" have very different widths there is no way to tell just by character count how many lines there will be.

    I'd definitely have more control with your method. I suppose while playtesting if a line looks odd I either add or subtract a line.

    Thank you for the suggestion (and for the short story you've made in your example)! I'll see how it works out.

  • daleinen Yes, with non-monospaced fonts you need to loop through each character and use SpriteFont.CharacterWidth(char) to calculate the correct width.

    Another option as R0J0 mentioned here is to use SpriteFont.TextWidth and TextHeight expressions. I believe for sprite font they are available immediately, you don't need to wait for the next tick. So you set text, read these expressions and adjust the box size accordingly.

  • I'm using text objects not sprite font. I didn't realize sprite font had CharacterWidth though. That would be a lot more accurate with my method of taking character count, and dividing that by an approximate line length, but it could still cut off text (depending on if the final word in a word wrapped line is "I" or "superimposed".

    I think there's no way around it but to manually place "newline" in the text to control the size of the text box (or the text box background 9-patch to be exact).

    But thank you both for the ideas. I appreciate it!

  • For text object I have this demo:

    The idea is to use another text object to obtain the width and height of text. It needs to be almost invisible, but not completely invisible (otherwise it will not be rendered), for example you can set its opacity to 0.1% or cover it by some sprite or move almost off the screen.

  • It worked! Thank you.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)