Search Unity

Unity UI Segmented Health Bar

Discussion in 'UGUI & TextMesh Pro' started by jtsmith1287, Feb 19, 2019.

  1. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    Hey gurus!

    I've been mulling over how to do segmented health bars (think MOBA, or most rpg style games in the last couple years) and everything I think of (which is not much) seems to be really expensive (performance) for the results.

    My two primary thoughts are
    a) some kind of material shader for the UI, but my limitation is that I don't know anything about shaders just yet. Handling the segments dynamically seems overly complicated. And by dynamic I mean that if each segment is, say, 20hp, if the object gains 30 max hp I need the bar to update on the fly with the appropriate number of segments.

    b) A horizontal layout group with a number of sliced images equal to the number of segments. This one seems silly but maybe not? Dynamically handling this again seems chaotic with either a lot of GC or a lot of images loaded that aren't being used.

    I found a few package on the unity store but the cost vs what I'm getting doesn't seem worth it, and likely I'd be purchasing it to learn how to do it myself.

    So for you UI experts out there, am I on the right track or is there a better way to do this?

    Thanks!
     
  2. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    The idea with the layout group is probably the easiest implementation. To avoid garbage, you should not delete the images. Instead simply set the image component to enabled = false.

    However, if the number of segments is fixed, you could prepare one sprite with all segments and add it to an image. set it to Filled with FillMethod Horizontal or Vertical (depending on your image).
    You can calculate the Fill amount like this:
    myImage.fillAmount = (float)currentHp / maxHp;


    However, if the max HP is dynamic, you would need a mix of Image Type Filled, Tiled and Sliced. That is not possible out of the box, but you could write it yourself theoretically.
    If you can live with non-sliced-images you can also solve it with a RawImage. Assign a texture to it which has the Wrap Mode "Repeat". you can change the W variable of the UV Rect to the number of current segments. However, you would also need to change the size of the rect transform accordingly.
     
  3. jtsmith1287

    jtsmith1287

    Joined:
    Aug 3, 2014
    Posts:
    787
    Thanks for the reply. Do you foresee any issues with having 50-100 health bars on screen (worst case scenario) with each of those having potentially dozens of gameobjects within that layout group? That's my primary fear with this implementation.
     
  4. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    I can imagine that it could impact the performance too much. But I guess you should do stress tests to be sure...
    It might be a good idea to put every health bar into a (sub)canvas, to not update all health bars when one changes.

    I think the raw image approach is the best, because it is flexible and probably is very fast regarding performance.