Search Unity

TextMesh Pro Word wrapping ignores carriage returns

Discussion in 'UGUI & TextMesh Pro' started by TheZombieKiller, Sep 4, 2018.

  1. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    If I have a carriage return in my text, word wrapping doesn't appear to take it into account:

    upload_2018-9-4_12-44-17.png

    The string in question is

    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\rAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

    The expected output would be this:

    upload_2018-9-4_12-44-59.png

    Is there any setting I could enable that would give me this behaviour?

    I assume this happens because the second line isn't considered the same line as the first, so the carriage return takes me to the beginning of that instead.
     
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Carriage return doesn't add a new line, it simply returns carriage back to the start of the line / writing position 0.

    Linefeed \n does both a carriage return and new line.

    Given the following text "AAAAAAAAAA\rBBBBBBBBBB\nCCCCCCCCCC"

    upload_2018-9-4_12-3-6.png

    As you can see the sequence of "B" are on top of the letter A as a result of the carriage return \r. The "C" are on their own line.
     
  3. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    Yeah, returning to the beginning of the line was the intention, I'm not trying to manually create new lines. I might not have made my example clear enough.

    The issue is that once the line gets too long and word wrapping kicks in, the carriage return seems to be ignored.
     
  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The behavior is correct but confusing as a result of using a long sequence of characters without any spaces or logical breaks in the sequence other than the \r.

    For instance let's look at the following sequence of characters: "AAAA\rBBBB"

    upload_2018-9-4_23-5-11.png

    In this first image, the behavior is as we expect.

    Now if I reduce the width of the text container, we get the following:

    upload_2018-9-4_23-6-15.png

    As the layout occurs, the first (3) A fit on the first line.
    The 4th A is pushed to line 2.
    Then the carriage return results in the first B being placed at the origin of line 2 over the letter A.
    But since we can't fit all (4) B on line two, we look for a logical place to break the line which is the carriage return.
    As such, the BBBB is pushed to line 3.
    Since the last B doesn't fit, it is pushed to line 4.

    Perhaps the expected behavior would be to have the (3) BBB stack on top of the A on line two but this means that carriage return would be ignored / excluded as a valid line break.
     
    TheZombieKiller likes this.
  5. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    Hmm, I see. Thanks for the explanation, I appreciate it.
    Would it be possible for the alternative behaviour to be added as an option at some point in the future?
     
  6. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Since I doubt your project is going to be using long string of letters "A"s, help me understand the use case for changing this behavior and what exactly you are trying to achieve in terms of layout of the text.

    Once I have a better understanding, I might be able to suggest a potential workaround and if not at least be clearer on the use.
     
  7. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    Essentially, I'm using it for the purpose of drawing a caret character (in this case, the underscore) on the input text of a developer console. Perhaps a bit of a strange way to go about it, sure, but it was easy enough to implement for a feature that shouldn't be overly complex.

    The text box gets a sanitized version of the input text followed by a carriage return, and then duplicates the input text (with zero alpha, so it's invisible) up to the index that the caret should appear on, and then adds the caret character (_).

    I wasn't able to find another method to easily draw overlapping text (within the same text object), so I resorted to this admittedly hacky method.
     
  8. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Why duplicate the text?

    If I understand correctly, you are simply trying to position the "_" under some character of the first text object. Correct?
     
  9. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    Yeah. I duplicate the text so that the underscore appears under the correct character.
     
  10. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Why not simply use the textInfo.charInfo[] of the source text object to lookup the origin of the character underneath which the "_" should appear. Then use a 2nd text object which only has one character (never changes and is static) and position it accordingly?

    Alternatively, you could still lookup the position of the origin of the character you need to place the caret under and then draw some simple geometry just like the underline is done in TextMesh Pro. This geometry could be a single quad and get stretched slightly to match the width of the character which could be determined using advance - origin of that character. You could setup the UV to point to the underline character as well.

    P.S. Since it is almost 3:00 am on my end, I am off to sleep but I'll check back tomorrow.
     
    Last edited: Sep 5, 2018
    TheZombieKiller likes this.
  11. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    Hmm, I'll need to play around with it, but I think using the origin + lineInfo should work. The main issue with having a separate text object is dealing with the TableLayoutGroup (from Unity UI Extensions) that the input & output text objects are under. I might just opt for manually handling the positioning of those two (as I did in a prior implementation) and ditch the layout group. Thanks for the help.