Search Unity

TextMeshProUGUI.Rebuild performance issue

Discussion in 'Unity UI (uGUI) & TextMesh Pro' started by LeFlown, Sep 12, 2019.

  1. LeFlown

    LeFlown

    Joined:
    Sep 11, 2013
    Posts:
    5
    Hi,

    I have a very simple scene with ten enemies. All of them have a Health Bar, and each time the player attacks them, damage numbers go floating everywhere.

    I have noticed that I have huge lag spikes when requesting UI elements to be displayed.
    Here is what I have in the (deep) profiler:
    TextMeshProUGUI performance.jpg

    And here is what I have in the hierarchy:
    Damage numbers...
    TextMeshProUGUI setup.jpg
    upload_2019-9-12_10-57-14.png
    ... and Health Bars
    TMP Health.jpg
    upload_2019-9-12_10-57-53.png

    UIManager is a simple gameobject. ScreenSpaceCanvas is the main canvas for all my runtime UI. UIDamageContainer and UIHealthBarContainer are simple gameobjects (I am using empty gameobjects as a way to organize my scene).

    Everything is instantiated beforehand. I don't change the size, nothing is setup with the Stretch anchors, and
    nothing has the PixelPerfect flag set to true.

    I have read on other threads that it might be cause by floating point error but I don't change anything except their positions and the texts.

    What can I do to improve the situation? Right now, this is just not working, and I don't know what I am doing wrong :( Please help!
     
  2. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    3,192
    There is a significant performance overhead to the Canvas system as changes to one object can trigger a re-layout of the entire hierarchy.

    For example, in the TMP Examples & Extras there is a scene called Benchmark (Floating Text). This scene instantiate 500 text objects. 250 static and 250 changing every single frame. This scene uses normal <TextMeshPro> objects which use the Mesh Renderer and depending on the target platform will still provide great performance. By contrast, doing the same thing where each text object have their own canvas simply kills performance. Ie. It wasn't even worth adding a example of that as it performed horribly due to the Canvas system overhead.

    It looks like each of your health bar has its own canvas. Are these health bar in screen space overlay, camera space or world space?

    Do these health bar have to be using the Canvas system in your design?
     
  3. LeFlown

    LeFlown

    Joined:
    Sep 11, 2013
    Posts:
    5
    Thank you for your reply!

    The health bars are in screen space overlay.
    I am going to try to remove the canvas from the UIDamage and see if there is a difference in performance.

    For the HealthBars using the canvas system, not necessarily but from what I could see on various tutorials, all of them were using canvas.
    If removing them is an option (that I didn't know about), what can I switch them for ?
    Can I get the same result (visually speaking) without canvas ?

    Sorry if those are stupid questions, I am definitely not a UI expert...
     
  4. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    3,192
    If you have to use the Canvas system, I would suggest grouping under (1) Canvas all static objects. Then grouping objects that will get frequent updates together under another canvas. These should each be top level. Ie. not children of another canvas.

    Alternatively, you should be able to arrive at the same result without using the Canvas for those health bars / more dynamic text objects.

    A few additional questions:
    How are your enemies / characters setup. I am assuming those are not using a Canvas. Correct?
    You could setup the healthbar text object as a child of the character.

    Take a look at the example scene I referenced above to see how the changing number are setup relative to their static "!" in that scene.

    BTW: There are two TMP text components available.
    There is the <TextMeshProUGUI> designed to work with the Canvas system and located in the UI - Text - TextMeshPro menu.

    There is the <TextMeshPro> component designed to work with the Mesh Renderer and located in 3D Object - Text - TextMeshPro.

    There is an overlay version of the TMP shaders available for overlay mode.
     
  5. LeFlown

    LeFlown

    Joined:
    Sep 11, 2013
    Posts:
    5
    My characters do not use canvas, it's a 3D game. Sorry I forgot to mention that.
    I could try to set the Healthbar child of the character but I would prefer not to as the UI is in an additive scene, not the same one as the one where I spawn the enemies. I can change that if it is how it should be.

    Everything child of the "ScreenSpaceCanvas" are dynamic objects (gonna rename the canvas...). All the static ones are already in different canvas.
     
  6. LeFlown

    LeFlown

    Joined:
    Sep 11, 2013
    Posts:
    5
    Quick update:
    I have removed all the unnecessary Canvas (in UIDamage and UIHealthBar), I now have basically just one big canvas, with everything else as Child. The performance boost is pretty good.
    I will try to change my setup using the other TMP component with the mesh renderer and let you know the results.