Search Unity

ui.text character limit

Discussion in 'UGUI & TextMesh Pro' started by johnpine, Oct 7, 2015.

  1. johnpine

    johnpine

    Joined:
    Sep 19, 2015
    Posts:
    26
    Well, seems that the UI.Text component has vertex limit of 65k.
    The new Unity ui uses 20 or 21 vertices per character.
    This makes the Text component to crash really easily.
    3120 characters is 80x39 its not even typical windows console size.
    Why is Unity using so many vertices per characters ? If you look at the wireframe view
    each character has mayhem of triangles. ngui had just 2 triangles ( 4 vertices ) and i can't see the quality
    difference.
    so how to determine the character limit to safely create new text components or canvases to go around the 65k vertex limit ? the font and language is changing run-time depending of country and localization.
     
  2. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,218
    It's kinda stupid they use geometry to do that instead of render text to texture and display on a quad IMO. Text doesn't change often, so even with text rendering being cpu bound for that, it wouldn't be much of performance hit.
     
  3. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,359
    So everytime I modify my text at runtime, I have to render it to a quad mesh?
    Btw quad mesh are additional drawcalls :p
     
  4. N1warhead

    N1warhead

    Joined:
    Mar 12, 2014
    Posts:
    3,884
    Wow are you serious, why would you make text geometry?
    That doesn't seem to make any sense imo.

    But I guess they had their reasons lol.
     
  5. RogDolos

    RogDolos

    Joined:
    Oct 16, 2012
    Posts:
    42
    This has been driving me crazy. Trying to do a chat window that scrolls and it will break on as few as 40 entries of chat depending on what's typed. Trying to break text into multiple Text elements doesn't help much, the vertices limit of the Canvas gets reached.

    The workaround seems to be to create multiple Canvas elements. That doesn't seem reasonable, how's that going to affect performance? Organizational nightmare too.
     
  6. Stephan-B

    Stephan-B

    Joined:
    Feb 23, 2011
    Posts:
    2,269
    UI.Text uses 4 vertices / 2 triangles per character. Now if you add the Outline or Shadow FX, those duplicate geometry which will then increase the vertices count to roughly what you have reported.

    The 65535 limit is in fact per Canvas. So when using Outline + Shadow FX, not only is performance not ideal but the geometry limitations comes around really fast.

    Alternatively, you could consider using TextMesh Pro where visual FX like Outline & Shadow are done at the shader level and are dynamic. Along with the reduced geometry, this yield a pretty significant performance boost.

    Here are the results of a benchmark I ran a few weeks ago which I posted here.
    I re-ran these same tests in Unity 5.2.2f1 and the results are the same. Using Text + Outline + Shadow, TextMesh Pro offers more than 10X performance and lower geometry count. Since TMP still uses the Canvas system, it is still subject to the 65535 vertices limits.

    P.S. In terms of the geometry limitations, when I have time, I will investigate if I could add an optimization where the geometry for characters that are not visible is not created. By not visible, I mean characters that would be outside the viewable area of a 2D RectMask for instance.
     
    Last edited: Oct 23, 2015
  7. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,051
    You need to cull what isn't actually visible. This also is a huge performance gain. If you have ~65k verts showing, it's going to be huge performance hit in the first place.
     
  8. Stephan-B

    Stephan-B

    Joined:
    Feb 23, 2011
    Posts:
    2,269
    When I get around to looking at this, I think it should provide another incremental performance boost for TextMesh Pro over Ui.Text. However, this is not a clear cut thing as having to rebuild the entire geometry each frame comes at a cost. Right now geometry that is not visible is handled by the shader which is efficient.

    The primary goal here is to look for ways to provide more flexibility around the 65K vertices limit per Canvas. Even if there was no additional performance gains, having characters that are not visible not count towards the 65K limit would be nice.
     
    Last edited: Oct 24, 2015
  9. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,051
    Sorry, I was using "cull" in the generic sense, not as in camera culling. You can have much more than 65k verts on a canvas, you just can't have more than 65k active.
     
  10. slcrubes

    slcrubes

    Joined:
    Sep 4, 2015
    Posts:
    11
    I just came across this same problem and I'm hoping for a potential solution.

    I am creating a game that contains a text output window, and I sequentially add text to this as the game progresses. There is enough text being generated during gameplay that it will easily exceed the character/vertex limit. The problem is that I want the player to be able to scroll back through the entire text transcript if desired. This isn't the kind of problem that can be solved with multiple Canvases, as far as I can tell.

    I began using a UI.Text component, and then later switched to TextMesh Pro, but as described above both seem to have the same issue.

    Are there any potential solutions for a scrollable text output window that can hold a very (very) long string of text like this?
     
    InglewoodTechnology likes this.
  11. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,218
    No, Unity would do it for you behind the scenes. Frankly I think it'd be best solution, to have text object only taking 4 verts/2 triangles and when ui text is changed, render it to texture and then display on ui text (it could be done on C++ side of Unity so it'd be very fast, especially when library capable of HW acceleration such as Cairo or Freetype is used).

    Even if it takes few miliseconds, it could be a) done in separate thread, b) wouldn't matter as large amounts of text (which are susceptible of this limit) doesn't change every frame if at all and small amounts of text that needs to change fast, such as fps counter takes little space so smaller texture can be generated (which is fast).

    Additionally, Unity could be smart about it and only employ "rendered texture on quad" method if trying to doing it using current method fails because of the vertex limit.
     
  12. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,051
    You need to break it up. Maybe by line breaks or story/action beats or something like that. One long string is hard to manage, and could lead to memory issues.

    Then all you have to do is draw them as blocks in your scroll window, and just turn off the ones that are visible on screen. Then turn them in when they are. I would leave thier container on, and just turn off the text element. That way you will keep the height of the scrollable area.
     
  13. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,051
    That would be way overkill. It would use a lot of unnecessary resources and would be slow. Since a render texture still requires drawing the ui elements first there isn't any savings in terms of scrolling. Unless you are suggesting rendering a massive area, but even then, you lose the ability to cull (manually or otherwise) mean you are trading verts which are cheap for texture memory which is expensive.

    And threading isn't going to help. New threads don't have access to the unity api, so you either have to pass it the rendered data which is pointless, or create a whole subsystem that can take text and render it to a texture, which is redundant. Moreover, the data you get back from the worker thread will still have to be turned back into a unity texture and rendered. Threads aren't the answer.

    The solution is to just not draw stuff out of the camera view. Either breaking into blocks, or being creative with string manipulation. (Though that could be tricky to right/smooth)
     
  14. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,218
    No, not the render texture. Just draw text itself on empty Texture2D using FreeType, Cairo or any other text rendering library and then apply it to a quad. As I said, Unity would do that behind the scenes.
     
  15. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,051
    You would have set those up as plugins and still have to write layout wrappers/methods that you could pass in all the settings you want, it would return byte data that you would have to apply to a texture2d and make the mesh. It's a lot of work to make workable. A lot of extra cpu, and and memory, especially texture memory redundant memory at that. Not a good trade off to save mesh, which is cheaper. Especially for the requirements of the op. That way will lead to crashes and performance issues.

    I am not sure what you by 'behind the scenes'. While it may not run on the primary thread, it isn't free.
     
  16. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,218
    Not if it'll be part of Unity's core, like physics and audio support.
     
  17. gresolio

    gresolio

    Joined:
    Jan 5, 2014
    Posts:
    17
    A simple but quite effective solution: http://forum.unity3d.com/threads/dynamic-scrolling-text-support.360026/

    In short: use one "Text" component per line (or more, up to limit), and use new "RectMask2D" instead of "Mask". "Vertical Layout Group" and "Content Size Fitter" will help you to place the items correctly. "Layout Element" would be useful to set the minimum height of the item. That's all. Good enough for large amount of text with scroll support :)
    My small project to test the idea: https://github.com/gresolio/Unity_UiTextLimit
     
  18. IzzySoft

    IzzySoft

    Joined:
    Feb 11, 2013
    Posts:
    376
    Would an Object Pool help at all?
     
  19. Stephan-B

    Stephan-B

    Joined:
    Feb 23, 2011
    Posts:
    2,269
    Just as an FYI, I did add in the latest release of TextMesh Pro a feature where text that exceeds the 65,535 vertices limit is automatically split into sub text objects. From a user's point of view, this is just a single text object which works like any other text object but happens to contain lots of characters.

    I'll try to build an example scene and do some tests.
     
    Martin_H likes this.
  20. gresolio

    gresolio

    Joined:
    Jan 5, 2014
    Posts:
    17
    Yes, it will be very helpful. Especially if you want to show only the last N messages and avoid re-creating game objects.

    Thank you for the excellent plugin :) Sounds very good, I'm looking forward to try your solution.
     
  21. Shrikky23

    Shrikky23

    Joined:
    Jun 30, 2013
    Posts:
    24
    This is still a problem with UI text :/ any updates? or we move to TextMeshPro by default?
     
  22. Murgilod

    Murgilod

    Joined:
    Nov 12, 2013
    Posts:
    10,140
    With TMP being available with the default install of Unity, there is really no reason not to use it anymore.
     
    softone, angrypenguin and Ryiah like this.